* reload1.c (eliminate_regs_1): Call gen_rtx_raw_SUBREG for SUBREGs
[official-gcc.git] / libgo / go / reflect / all_test.go
blob859de7c86706c0bae9ad5e27adc10df1394f7fe3
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 var sink interface{}
31 func TestBool(t *testing.T) {
32 v := ValueOf(true)
33 if v.Bool() != true {
34 t.Fatal("ValueOf(true).Bool() = false")
38 type integer int
39 type T struct {
40 a int
41 b float64
42 c string
43 d *int
46 type pair struct {
47 i interface{}
48 s string
51 func assert(t *testing.T, s, want string) {
52 if s != want {
53 t.Errorf("have %#q want %#q", s, want)
57 var typeTests = []pair{
58 {struct{ x int }{}, "int"},
59 {struct{ x int8 }{}, "int8"},
60 {struct{ x int16 }{}, "int16"},
61 {struct{ x int32 }{}, "int32"},
62 {struct{ x int64 }{}, "int64"},
63 {struct{ x uint }{}, "uint"},
64 {struct{ x uint8 }{}, "uint8"},
65 {struct{ x uint16 }{}, "uint16"},
66 {struct{ x uint32 }{}, "uint32"},
67 {struct{ x uint64 }{}, "uint64"},
68 {struct{ x float32 }{}, "float32"},
69 {struct{ x float64 }{}, "float64"},
70 {struct{ x int8 }{}, "int8"},
71 {struct{ x (**int8) }{}, "**int8"},
72 {struct{ x (**integer) }{}, "**reflect_test.integer"},
73 {struct{ x ([32]int32) }{}, "[32]int32"},
74 {struct{ x ([]int8) }{}, "[]int8"},
75 {struct{ x (map[string]int32) }{}, "map[string]int32"},
76 {struct{ x (chan<- string) }{}, "chan<- string"},
77 {struct {
78 x struct {
79 c chan *int32
80 d float32
82 }{},
83 "struct { c chan *int32; d float32 }",
85 {struct{ x (func(a int8, b int32)) }{}, "func(int8, int32)"},
86 {struct {
87 x struct {
88 c func(chan *integer, *int8)
90 }{},
91 "struct { c func(chan *reflect_test.integer, *int8) }",
93 {struct {
94 x struct {
95 a int8
96 b int32
98 }{},
99 "struct { a int8; b int32 }",
101 {struct {
102 x struct {
103 a int8
104 b int8
105 c int32
107 }{},
108 "struct { a int8; b int8; c int32 }",
110 {struct {
111 x struct {
112 a int8
113 b int8
114 c int8
115 d int32
117 }{},
118 "struct { a int8; b int8; c int8; d int32 }",
120 {struct {
121 x struct {
122 a int8
123 b int8
124 c int8
125 d int8
126 e int32
128 }{},
129 "struct { a int8; b int8; c int8; d int8; e int32 }",
131 {struct {
132 x struct {
133 a int8
134 b int8
135 c int8
136 d int8
137 e int8
138 f int32
140 }{},
141 "struct { a int8; b int8; c int8; d int8; e int8; f int32 }",
143 {struct {
144 x struct {
145 a int8 `reflect:"hi there"`
147 }{},
148 `struct { a int8 "reflect:\"hi there\"" }`,
150 {struct {
151 x struct {
152 a int8 `reflect:"hi \x00there\t\n\"\\"`
154 }{},
155 `struct { a int8 "reflect:\"hi \\x00there\\t\\n\\\"\\\\\"" }`,
157 {struct {
158 x struct {
159 f func(args ...int)
161 }{},
162 "struct { f func(...int) }",
164 {struct {
165 x (interface {
166 a(func(func(int) int) func(func(int)) int)
169 }{},
170 "interface { reflect_test.a(func(func(int) int) func(func(int)) int); reflect_test.b() }",
174 var valueTests = []pair{
175 {new(int), "132"},
176 {new(int8), "8"},
177 {new(int16), "16"},
178 {new(int32), "32"},
179 {new(int64), "64"},
180 {new(uint), "132"},
181 {new(uint8), "8"},
182 {new(uint16), "16"},
183 {new(uint32), "32"},
184 {new(uint64), "64"},
185 {new(float32), "256.25"},
186 {new(float64), "512.125"},
187 {new(complex64), "532.125+10i"},
188 {new(complex128), "564.25+1i"},
189 {new(string), "stringy cheese"},
190 {new(bool), "true"},
191 {new(*int8), "*int8(0)"},
192 {new(**int8), "**int8(0)"},
193 {new([5]int32), "[5]int32{0, 0, 0, 0, 0}"},
194 {new(**integer), "**reflect_test.integer(0)"},
195 {new(map[string]int32), "map[string]int32{<can't iterate on maps>}"},
196 {new(chan<- string), "chan<- string"},
197 {new(func(a int8, b int32)), "func(int8, int32)(0)"},
198 {new(struct {
199 c chan *int32
200 d float32
202 "struct { c chan *int32; d float32 }{chan *int32, 0}",
204 {new(struct{ c func(chan *integer, *int8) }),
205 "struct { c func(chan *reflect_test.integer, *int8) }{func(chan *reflect_test.integer, *int8)(0)}",
207 {new(struct {
208 a int8
209 b int32
211 "struct { a int8; b int32 }{0, 0}",
213 {new(struct {
214 a int8
215 b int8
216 c int32
218 "struct { a int8; b int8; c int32 }{0, 0, 0}",
222 func testType(t *testing.T, i int, typ Type, want string) {
223 s := typ.String()
224 if s != want {
225 t.Errorf("#%d: have %#q, want %#q", i, s, want)
229 func TestTypes(t *testing.T) {
230 for i, tt := range typeTests {
231 testType(t, i, ValueOf(tt.i).Field(0).Type(), tt.s)
235 func TestSet(t *testing.T) {
236 for i, tt := range valueTests {
237 v := ValueOf(tt.i)
238 v = v.Elem()
239 switch v.Kind() {
240 case Int:
241 v.SetInt(132)
242 case Int8:
243 v.SetInt(8)
244 case Int16:
245 v.SetInt(16)
246 case Int32:
247 v.SetInt(32)
248 case Int64:
249 v.SetInt(64)
250 case Uint:
251 v.SetUint(132)
252 case Uint8:
253 v.SetUint(8)
254 case Uint16:
255 v.SetUint(16)
256 case Uint32:
257 v.SetUint(32)
258 case Uint64:
259 v.SetUint(64)
260 case Float32:
261 v.SetFloat(256.25)
262 case Float64:
263 v.SetFloat(512.125)
264 case Complex64:
265 v.SetComplex(532.125 + 10i)
266 case Complex128:
267 v.SetComplex(564.25 + 1i)
268 case String:
269 v.SetString("stringy cheese")
270 case Bool:
271 v.SetBool(true)
273 s := valueToString(v)
274 if s != tt.s {
275 t.Errorf("#%d: have %#q, want %#q", i, s, tt.s)
280 func TestSetValue(t *testing.T) {
281 for i, tt := range valueTests {
282 v := ValueOf(tt.i).Elem()
283 switch v.Kind() {
284 case Int:
285 v.Set(ValueOf(int(132)))
286 case Int8:
287 v.Set(ValueOf(int8(8)))
288 case Int16:
289 v.Set(ValueOf(int16(16)))
290 case Int32:
291 v.Set(ValueOf(int32(32)))
292 case Int64:
293 v.Set(ValueOf(int64(64)))
294 case Uint:
295 v.Set(ValueOf(uint(132)))
296 case Uint8:
297 v.Set(ValueOf(uint8(8)))
298 case Uint16:
299 v.Set(ValueOf(uint16(16)))
300 case Uint32:
301 v.Set(ValueOf(uint32(32)))
302 case Uint64:
303 v.Set(ValueOf(uint64(64)))
304 case Float32:
305 v.Set(ValueOf(float32(256.25)))
306 case Float64:
307 v.Set(ValueOf(512.125))
308 case Complex64:
309 v.Set(ValueOf(complex64(532.125 + 10i)))
310 case Complex128:
311 v.Set(ValueOf(complex128(564.25 + 1i)))
312 case String:
313 v.Set(ValueOf("stringy cheese"))
314 case Bool:
315 v.Set(ValueOf(true))
317 s := valueToString(v)
318 if s != tt.s {
319 t.Errorf("#%d: have %#q, want %#q", i, s, tt.s)
324 var _i = 7
326 var valueToStringTests = []pair{
327 {123, "123"},
328 {123.5, "123.5"},
329 {byte(123), "123"},
330 {"abc", "abc"},
331 {T{123, 456.75, "hello", &_i}, "reflect_test.T{123, 456.75, hello, *int(&7)}"},
332 {new(chan *T), "*chan *reflect_test.T(&chan *reflect_test.T)"},
333 {[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
334 {&[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})"},
335 {[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
336 {&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "*[]int(&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})"},
339 func TestValueToString(t *testing.T) {
340 for i, test := range valueToStringTests {
341 s := valueToString(ValueOf(test.i))
342 if s != test.s {
343 t.Errorf("#%d: have %#q, want %#q", i, s, test.s)
348 func TestArrayElemSet(t *testing.T) {
349 v := ValueOf(&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}).Elem()
350 v.Index(4).SetInt(123)
351 s := valueToString(v)
352 const want = "[10]int{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"
353 if s != want {
354 t.Errorf("[10]int: have %#q want %#q", s, want)
357 v = ValueOf([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
358 v.Index(4).SetInt(123)
359 s = valueToString(v)
360 const want1 = "[]int{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"
361 if s != want1 {
362 t.Errorf("[]int: have %#q want %#q", s, want1)
366 func TestPtrPointTo(t *testing.T) {
367 var ip *int32
368 var i int32 = 1234
369 vip := ValueOf(&ip)
370 vi := ValueOf(&i).Elem()
371 vip.Elem().Set(vi.Addr())
372 if *ip != 1234 {
373 t.Errorf("got %d, want 1234", *ip)
376 ip = nil
377 vp := ValueOf(&ip).Elem()
378 vp.Set(Zero(vp.Type()))
379 if ip != nil {
380 t.Errorf("got non-nil (%p), want nil", ip)
384 func TestPtrSetNil(t *testing.T) {
385 var i int32 = 1234
386 ip := &i
387 vip := ValueOf(&ip)
388 vip.Elem().Set(Zero(vip.Elem().Type()))
389 if ip != nil {
390 t.Errorf("got non-nil (%d), want nil", *ip)
394 func TestMapSetNil(t *testing.T) {
395 m := make(map[string]int)
396 vm := ValueOf(&m)
397 vm.Elem().Set(Zero(vm.Elem().Type()))
398 if m != nil {
399 t.Errorf("got non-nil (%p), want nil", m)
403 func TestAll(t *testing.T) {
404 testType(t, 1, TypeOf((int8)(0)), "int8")
405 testType(t, 2, TypeOf((*int8)(nil)).Elem(), "int8")
407 typ := TypeOf((*struct {
408 c chan *int32
409 d float32
410 })(nil))
411 testType(t, 3, typ, "*struct { c chan *int32; d float32 }")
412 etyp := typ.Elem()
413 testType(t, 4, etyp, "struct { c chan *int32; d float32 }")
414 styp := etyp
415 f := styp.Field(0)
416 testType(t, 5, f.Type, "chan *int32")
418 f, present := styp.FieldByName("d")
419 if !present {
420 t.Errorf("FieldByName says present field is absent")
422 testType(t, 6, f.Type, "float32")
424 f, present = styp.FieldByName("absent")
425 if present {
426 t.Errorf("FieldByName says absent field is present")
429 typ = TypeOf([32]int32{})
430 testType(t, 7, typ, "[32]int32")
431 testType(t, 8, typ.Elem(), "int32")
433 typ = TypeOf((map[string]*int32)(nil))
434 testType(t, 9, typ, "map[string]*int32")
435 mtyp := typ
436 testType(t, 10, mtyp.Key(), "string")
437 testType(t, 11, mtyp.Elem(), "*int32")
439 typ = TypeOf((chan<- string)(nil))
440 testType(t, 12, typ, "chan<- string")
441 testType(t, 13, typ.Elem(), "string")
443 // make sure tag strings are not part of element type
444 typ = TypeOf(struct {
445 d []uint32 `reflect:"TAG"`
446 }{}).Field(0).Type
447 testType(t, 14, typ, "[]uint32")
450 func TestInterfaceGet(t *testing.T) {
451 var inter struct {
452 E interface{}
454 inter.E = 123.456
455 v1 := ValueOf(&inter)
456 v2 := v1.Elem().Field(0)
457 assert(t, v2.Type().String(), "interface {}")
458 i2 := v2.Interface()
459 v3 := ValueOf(i2)
460 assert(t, v3.Type().String(), "float64")
463 func TestInterfaceValue(t *testing.T) {
464 var inter struct {
465 E interface{}
467 inter.E = 123.456
468 v1 := ValueOf(&inter)
469 v2 := v1.Elem().Field(0)
470 assert(t, v2.Type().String(), "interface {}")
471 v3 := v2.Elem()
472 assert(t, v3.Type().String(), "float64")
474 i3 := v2.Interface()
475 if _, ok := i3.(float64); !ok {
476 t.Error("v2.Interface() did not return float64, got ", TypeOf(i3))
480 func TestFunctionValue(t *testing.T) {
481 var x interface{} = func() {}
482 v := ValueOf(x)
483 if fmt.Sprint(v.Interface()) != fmt.Sprint(x) {
484 t.Fatalf("TestFunction returned wrong pointer")
486 assert(t, v.Type().String(), "func()")
489 var appendTests = []struct {
490 orig, extra []int
492 {make([]int, 2, 4), []int{22}},
493 {make([]int, 2, 4), []int{22, 33, 44}},
496 func sameInts(x, y []int) bool {
497 if len(x) != len(y) {
498 return false
500 for i, xx := range x {
501 if xx != y[i] {
502 return false
505 return true
508 func TestAppend(t *testing.T) {
509 for i, test := range appendTests {
510 origLen, extraLen := len(test.orig), len(test.extra)
511 want := append(test.orig, test.extra...)
512 // Convert extra from []int to []Value.
513 e0 := make([]Value, len(test.extra))
514 for j, e := range test.extra {
515 e0[j] = ValueOf(e)
517 // Convert extra from []int to *SliceValue.
518 e1 := ValueOf(test.extra)
519 // Test Append.
520 a0 := ValueOf(test.orig)
521 have0 := Append(a0, e0...).Interface().([]int)
522 if !sameInts(have0, want) {
523 t.Errorf("Append #%d: have %v, want %v (%p %p)", i, have0, want, test.orig, have0)
525 // Check that the orig and extra slices were not modified.
526 if len(test.orig) != origLen {
527 t.Errorf("Append #%d origLen: have %v, want %v", i, len(test.orig), origLen)
529 if len(test.extra) != extraLen {
530 t.Errorf("Append #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
532 // Test AppendSlice.
533 a1 := ValueOf(test.orig)
534 have1 := AppendSlice(a1, e1).Interface().([]int)
535 if !sameInts(have1, want) {
536 t.Errorf("AppendSlice #%d: have %v, want %v", i, have1, want)
538 // Check that the orig and extra slices were not modified.
539 if len(test.orig) != origLen {
540 t.Errorf("AppendSlice #%d origLen: have %v, want %v", i, len(test.orig), origLen)
542 if len(test.extra) != extraLen {
543 t.Errorf("AppendSlice #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
548 func TestCopy(t *testing.T) {
549 a := []int{1, 2, 3, 4, 10, 9, 8, 7}
550 b := []int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
551 c := []int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
552 for i := 0; i < len(b); i++ {
553 if b[i] != c[i] {
554 t.Fatalf("b != c before test")
557 a1 := a
558 b1 := b
559 aa := ValueOf(&a1).Elem()
560 ab := ValueOf(&b1).Elem()
561 for tocopy := 1; tocopy <= 7; tocopy++ {
562 aa.SetLen(tocopy)
563 Copy(ab, aa)
564 aa.SetLen(8)
565 for i := 0; i < tocopy; i++ {
566 if a[i] != b[i] {
567 t.Errorf("(i) tocopy=%d a[%d]=%d, b[%d]=%d",
568 tocopy, i, a[i], i, b[i])
571 for i := tocopy; i < len(b); i++ {
572 if b[i] != c[i] {
573 if i < len(a) {
574 t.Errorf("(ii) tocopy=%d a[%d]=%d, b[%d]=%d, c[%d]=%d",
575 tocopy, i, a[i], i, b[i], i, c[i])
576 } else {
577 t.Errorf("(iii) tocopy=%d b[%d]=%d, c[%d]=%d",
578 tocopy, i, b[i], i, c[i])
580 } else {
581 t.Logf("tocopy=%d elem %d is okay\n", tocopy, i)
587 func TestCopyArray(t *testing.T) {
588 a := [8]int{1, 2, 3, 4, 10, 9, 8, 7}
589 b := [11]int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
590 c := b
591 aa := ValueOf(&a).Elem()
592 ab := ValueOf(&b).Elem()
593 Copy(ab, aa)
594 for i := 0; i < len(a); i++ {
595 if a[i] != b[i] {
596 t.Errorf("(i) a[%d]=%d, b[%d]=%d", i, a[i], i, b[i])
599 for i := len(a); i < len(b); i++ {
600 if b[i] != c[i] {
601 t.Errorf("(ii) b[%d]=%d, c[%d]=%d", i, b[i], i, c[i])
602 } else {
603 t.Logf("elem %d is okay\n", i)
608 func TestBigUnnamedStruct(t *testing.T) {
609 b := struct{ a, b, c, d int64 }{1, 2, 3, 4}
610 v := ValueOf(b)
611 b1 := v.Interface().(struct {
612 a, b, c, d int64
614 if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d {
615 t.Errorf("ValueOf(%v).Interface().(*Big) = %v", b, b1)
619 type big struct {
620 a, b, c, d, e int64
623 func TestBigStruct(t *testing.T) {
624 b := big{1, 2, 3, 4, 5}
625 v := ValueOf(b)
626 b1 := v.Interface().(big)
627 if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d || b1.e != b.e {
628 t.Errorf("ValueOf(%v).Interface().(big) = %v", b, b1)
632 type Basic struct {
633 x int
634 y float32
637 type NotBasic Basic
639 type DeepEqualTest struct {
640 a, b interface{}
641 eq bool
644 // Simple functions for DeepEqual tests.
645 var (
646 fn1 func() // nil.
647 fn2 func() // nil.
648 fn3 = func() { fn1() } // Not nil.
651 type self struct{}
653 type Loop *Loop
654 type Loopy interface{}
656 var loop1, loop2 Loop
657 var loopy1, loopy2 Loopy
659 func init() {
660 loop1 = &loop2
661 loop2 = &loop1
663 loopy1 = &loopy2
664 loopy2 = &loopy1
667 var deepEqualTests = []DeepEqualTest{
668 // Equalities
669 {nil, nil, true},
670 {1, 1, true},
671 {int32(1), int32(1), true},
672 {0.5, 0.5, true},
673 {float32(0.5), float32(0.5), true},
674 {"hello", "hello", true},
675 {make([]int, 10), make([]int, 10), true},
676 {&[3]int{1, 2, 3}, &[3]int{1, 2, 3}, true},
677 {Basic{1, 0.5}, Basic{1, 0.5}, true},
678 {error(nil), error(nil), true},
679 {map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true},
680 {fn1, fn2, true},
682 // Inequalities
683 {1, 2, false},
684 {int32(1), int32(2), false},
685 {0.5, 0.6, false},
686 {float32(0.5), float32(0.6), false},
687 {"hello", "hey", false},
688 {make([]int, 10), make([]int, 11), false},
689 {&[3]int{1, 2, 3}, &[3]int{1, 2, 4}, false},
690 {Basic{1, 0.5}, Basic{1, 0.6}, false},
691 {Basic{1, 0}, Basic{2, 0}, false},
692 {map[int]string{1: "one", 3: "two"}, map[int]string{2: "two", 1: "one"}, false},
693 {map[int]string{1: "one", 2: "txo"}, map[int]string{2: "two", 1: "one"}, false},
694 {map[int]string{1: "one"}, map[int]string{2: "two", 1: "one"}, false},
695 {map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false},
696 {nil, 1, false},
697 {1, nil, false},
698 {fn1, fn3, false},
699 {fn3, fn3, false},
700 {[][]int{{1}}, [][]int{{2}}, false},
701 {math.NaN(), math.NaN(), false},
702 {&[1]float64{math.NaN()}, &[1]float64{math.NaN()}, false},
703 {&[1]float64{math.NaN()}, self{}, true},
704 {[]float64{math.NaN()}, []float64{math.NaN()}, false},
705 {[]float64{math.NaN()}, self{}, true},
706 {map[float64]float64{math.NaN(): 1}, map[float64]float64{1: 2}, false},
707 {map[float64]float64{math.NaN(): 1}, self{}, true},
709 // Nil vs empty: not the same.
710 {[]int{}, []int(nil), false},
711 {[]int{}, []int{}, true},
712 {[]int(nil), []int(nil), true},
713 {map[int]int{}, map[int]int(nil), false},
714 {map[int]int{}, map[int]int{}, true},
715 {map[int]int(nil), map[int]int(nil), true},
717 // Mismatched types
718 {1, 1.0, false},
719 {int32(1), int64(1), false},
720 {0.5, "hello", false},
721 {[]int{1, 2, 3}, [3]int{1, 2, 3}, false},
722 {&[3]interface{}{1, 2, 4}, &[3]interface{}{1, 2, "s"}, false},
723 {Basic{1, 0.5}, NotBasic{1, 0.5}, false},
724 {map[uint]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, false},
726 // Possible loops.
727 {&loop1, &loop1, true},
728 {&loop1, &loop2, true},
729 {&loopy1, &loopy1, true},
730 {&loopy1, &loopy2, true},
733 func TestDeepEqual(t *testing.T) {
734 for _, test := range deepEqualTests {
735 if test.b == (self{}) {
736 test.b = test.a
738 if r := DeepEqual(test.a, test.b); r != test.eq {
739 t.Errorf("DeepEqual(%v, %v) = %v, want %v", test.a, test.b, r, test.eq)
744 func TestTypeOf(t *testing.T) {
745 // Special case for nil
746 if typ := TypeOf(nil); typ != nil {
747 t.Errorf("expected nil type for nil value; got %v", typ)
749 for _, test := range deepEqualTests {
750 v := ValueOf(test.a)
751 if !v.IsValid() {
752 continue
754 typ := TypeOf(test.a)
755 if typ != v.Type() {
756 t.Errorf("TypeOf(%v) = %v, but ValueOf(%v).Type() = %v", test.a, typ, test.a, v.Type())
761 type Recursive struct {
762 x int
763 r *Recursive
766 func TestDeepEqualRecursiveStruct(t *testing.T) {
767 a, b := new(Recursive), new(Recursive)
768 *a = Recursive{12, a}
769 *b = Recursive{12, b}
770 if !DeepEqual(a, b) {
771 t.Error("DeepEqual(recursive same) = false, want true")
775 type _Complex struct {
776 a int
777 b [3]*_Complex
778 c *string
779 d map[float64]float64
782 func TestDeepEqualComplexStruct(t *testing.T) {
783 m := make(map[float64]float64)
784 stra, strb := "hello", "hello"
785 a, b := new(_Complex), new(_Complex)
786 *a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m}
787 *b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m}
788 if !DeepEqual(a, b) {
789 t.Error("DeepEqual(complex same) = false, want true")
793 func TestDeepEqualComplexStructInequality(t *testing.T) {
794 m := make(map[float64]float64)
795 stra, strb := "hello", "helloo" // Difference is here
796 a, b := new(_Complex), new(_Complex)
797 *a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m}
798 *b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m}
799 if DeepEqual(a, b) {
800 t.Error("DeepEqual(complex different) = true, want false")
804 type UnexpT struct {
805 m map[int]int
808 func TestDeepEqualUnexportedMap(t *testing.T) {
809 // Check that DeepEqual can look at unexported fields.
810 x1 := UnexpT{map[int]int{1: 2}}
811 x2 := UnexpT{map[int]int{1: 2}}
812 if !DeepEqual(&x1, &x2) {
813 t.Error("DeepEqual(x1, x2) = false, want true")
816 y1 := UnexpT{map[int]int{2: 3}}
817 if DeepEqual(&x1, &y1) {
818 t.Error("DeepEqual(x1, y1) = true, want false")
822 func check2ndField(x interface{}, offs uintptr, t *testing.T) {
823 s := ValueOf(x)
824 f := s.Type().Field(1)
825 if f.Offset != offs {
826 t.Error("mismatched offsets in structure alignment:", f.Offset, offs)
830 // Check that structure alignment & offsets viewed through reflect agree with those
831 // from the compiler itself.
832 func TestAlignment(t *testing.T) {
833 type T1inner struct {
834 a int
836 type T1 struct {
837 T1inner
838 f int
840 type T2inner struct {
841 a, b int
843 type T2 struct {
844 T2inner
845 f int
848 x := T1{T1inner{2}, 17}
849 check2ndField(x, uintptr(unsafe.Pointer(&x.f))-uintptr(unsafe.Pointer(&x)), t)
851 x1 := T2{T2inner{2, 3}, 17}
852 check2ndField(x1, uintptr(unsafe.Pointer(&x1.f))-uintptr(unsafe.Pointer(&x1)), t)
855 func Nil(a interface{}, t *testing.T) {
856 n := ValueOf(a).Field(0)
857 if !n.IsNil() {
858 t.Errorf("%v should be nil", a)
862 func NotNil(a interface{}, t *testing.T) {
863 n := ValueOf(a).Field(0)
864 if n.IsNil() {
865 t.Errorf("value of type %v should not be nil", ValueOf(a).Type().String())
869 func TestIsNil(t *testing.T) {
870 // These implement IsNil.
871 // Wrap in extra struct to hide interface type.
872 doNil := []interface{}{
873 struct{ x *int }{},
874 struct{ x interface{} }{},
875 struct{ x map[string]int }{},
876 struct{ x func() bool }{},
877 struct{ x chan int }{},
878 struct{ x []string }{},
880 for _, ts := range doNil {
881 ty := TypeOf(ts).Field(0).Type
882 v := Zero(ty)
883 v.IsNil() // panics if not okay to call
886 // Check the implementations
887 var pi struct {
888 x *int
890 Nil(pi, t)
891 pi.x = new(int)
892 NotNil(pi, t)
894 var si struct {
895 x []int
897 Nil(si, t)
898 si.x = make([]int, 10)
899 NotNil(si, t)
901 var ci struct {
902 x chan int
904 Nil(ci, t)
905 ci.x = make(chan int)
906 NotNil(ci, t)
908 var mi struct {
909 x map[int]int
911 Nil(mi, t)
912 mi.x = make(map[int]int)
913 NotNil(mi, t)
915 var ii struct {
916 x interface{}
918 Nil(ii, t)
919 ii.x = 2
920 NotNil(ii, t)
922 var fi struct {
923 x func(t *testing.T)
925 Nil(fi, t)
926 fi.x = TestIsNil
927 NotNil(fi, t)
930 func TestInterfaceExtraction(t *testing.T) {
931 var s struct {
932 W io.Writer
935 s.W = os.Stdout
936 v := Indirect(ValueOf(&s)).Field(0).Interface()
937 if v != s.W.(interface{}) {
938 t.Error("Interface() on interface: ", v, s.W)
942 func TestNilPtrValueSub(t *testing.T) {
943 var pi *int
944 if pv := ValueOf(pi); pv.Elem().IsValid() {
945 t.Error("ValueOf((*int)(nil)).Elem().IsValid()")
949 func TestMap(t *testing.T) {
950 m := map[string]int{"a": 1, "b": 2}
951 mv := ValueOf(m)
952 if n := mv.Len(); n != len(m) {
953 t.Errorf("Len = %d, want %d", n, len(m))
955 keys := mv.MapKeys()
956 newmap := MakeMap(mv.Type())
957 for k, v := range m {
958 // Check that returned Keys match keys in range.
959 // These aren't required to be in the same order.
960 seen := false
961 for _, kv := range keys {
962 if kv.String() == k {
963 seen = true
964 break
967 if !seen {
968 t.Errorf("Missing key %q", k)
971 // Check that value lookup is correct.
972 vv := mv.MapIndex(ValueOf(k))
973 if vi := vv.Int(); vi != int64(v) {
974 t.Errorf("Key %q: have value %d, want %d", k, vi, v)
977 // Copy into new map.
978 newmap.SetMapIndex(ValueOf(k), ValueOf(v))
980 vv := mv.MapIndex(ValueOf("not-present"))
981 if vv.IsValid() {
982 t.Errorf("Invalid key: got non-nil value %s", valueToString(vv))
985 newm := newmap.Interface().(map[string]int)
986 if len(newm) != len(m) {
987 t.Errorf("length after copy: newm=%d, m=%d", len(newm), len(m))
990 for k, v := range newm {
991 mv, ok := m[k]
992 if mv != v {
993 t.Errorf("newm[%q] = %d, but m[%q] = %d, %v", k, v, k, mv, ok)
997 newmap.SetMapIndex(ValueOf("a"), Value{})
998 v, ok := newm["a"]
999 if ok {
1000 t.Errorf("newm[\"a\"] = %d after delete", v)
1003 mv = ValueOf(&m).Elem()
1004 mv.Set(Zero(mv.Type()))
1005 if m != nil {
1006 t.Errorf("mv.Set(nil) failed")
1010 func TestNilMap(t *testing.T) {
1011 var m map[string]int
1012 mv := ValueOf(m)
1013 keys := mv.MapKeys()
1014 if len(keys) != 0 {
1015 t.Errorf(">0 keys for nil map: %v", keys)
1018 // Check that value for missing key is zero.
1019 x := mv.MapIndex(ValueOf("hello"))
1020 if x.Kind() != Invalid {
1021 t.Errorf("m.MapIndex(\"hello\") for nil map = %v, want Invalid Value", x)
1024 // Check big value too.
1025 var mbig map[string][10 << 20]byte
1026 x = ValueOf(mbig).MapIndex(ValueOf("hello"))
1027 if x.Kind() != Invalid {
1028 t.Errorf("mbig.MapIndex(\"hello\") for nil map = %v, want Invalid Value", x)
1031 // Test that deletes from a nil map succeed.
1032 mv.SetMapIndex(ValueOf("hi"), Value{})
1035 func TestChan(t *testing.T) {
1036 for loop := 0; loop < 2; loop++ {
1037 var c chan int
1038 var cv Value
1040 // check both ways to allocate channels
1041 switch loop {
1042 case 1:
1043 c = make(chan int, 1)
1044 cv = ValueOf(c)
1045 case 0:
1046 cv = MakeChan(TypeOf(c), 1)
1047 c = cv.Interface().(chan int)
1050 // Send
1051 cv.Send(ValueOf(2))
1052 if i := <-c; i != 2 {
1053 t.Errorf("reflect Send 2, native recv %d", i)
1056 // Recv
1057 c <- 3
1058 if i, ok := cv.Recv(); i.Int() != 3 || !ok {
1059 t.Errorf("native send 3, reflect Recv %d, %t", i.Int(), ok)
1062 // TryRecv fail
1063 val, ok := cv.TryRecv()
1064 if val.IsValid() || ok {
1065 t.Errorf("TryRecv on empty chan: %s, %t", valueToString(val), ok)
1068 // TryRecv success
1069 c <- 4
1070 val, ok = cv.TryRecv()
1071 if !val.IsValid() {
1072 t.Errorf("TryRecv on ready chan got nil")
1073 } else if i := val.Int(); i != 4 || !ok {
1074 t.Errorf("native send 4, TryRecv %d, %t", i, ok)
1077 // TrySend fail
1078 c <- 100
1079 ok = cv.TrySend(ValueOf(5))
1080 i := <-c
1081 if ok {
1082 t.Errorf("TrySend on full chan succeeded: value %d", i)
1085 // TrySend success
1086 ok = cv.TrySend(ValueOf(6))
1087 if !ok {
1088 t.Errorf("TrySend on empty chan failed")
1089 select {
1090 case x := <-c:
1091 t.Errorf("TrySend failed but it did send %d", x)
1092 default:
1094 } else {
1095 if i = <-c; i != 6 {
1096 t.Errorf("TrySend 6, recv %d", i)
1100 // Close
1101 c <- 123
1102 cv.Close()
1103 if i, ok := cv.Recv(); i.Int() != 123 || !ok {
1104 t.Errorf("send 123 then close; Recv %d, %t", i.Int(), ok)
1106 if i, ok := cv.Recv(); i.Int() != 0 || ok {
1107 t.Errorf("after close Recv %d, %t", i.Int(), ok)
1111 // check creation of unbuffered channel
1112 var c chan int
1113 cv := MakeChan(TypeOf(c), 0)
1114 c = cv.Interface().(chan int)
1115 if cv.TrySend(ValueOf(7)) {
1116 t.Errorf("TrySend on sync chan succeeded")
1118 if v, ok := cv.TryRecv(); v.IsValid() || ok {
1119 t.Errorf("TryRecv on sync chan succeeded: isvalid=%v ok=%v", v.IsValid(), ok)
1122 // len/cap
1123 cv = MakeChan(TypeOf(c), 10)
1124 c = cv.Interface().(chan int)
1125 for i := 0; i < 3; i++ {
1126 c <- i
1128 if l, m := cv.Len(), cv.Cap(); l != len(c) || m != cap(c) {
1129 t.Errorf("Len/Cap = %d/%d want %d/%d", l, m, len(c), cap(c))
1133 // caseInfo describes a single case in a select test.
1134 type caseInfo struct {
1135 desc string
1136 canSelect bool
1137 recv Value
1138 closed bool
1139 helper func()
1140 panic bool
1143 var allselect = flag.Bool("allselect", false, "exhaustive select test")
1145 func TestSelect(t *testing.T) {
1146 selectWatch.once.Do(func() { go selectWatcher() })
1148 var x exhaustive
1149 nch := 0
1150 newop := func(n int, cap int) (ch, val Value) {
1151 nch++
1152 if nch%101%2 == 1 {
1153 c := make(chan int, cap)
1154 ch = ValueOf(c)
1155 val = ValueOf(n)
1156 } else {
1157 c := make(chan string, cap)
1158 ch = ValueOf(c)
1159 val = ValueOf(fmt.Sprint(n))
1161 return
1164 for n := 0; x.Next(); n++ {
1165 if testing.Short() && n >= 1000 {
1166 break
1168 if n >= 100000 && !*allselect {
1169 break
1171 if n%100000 == 0 && testing.Verbose() {
1172 println("TestSelect", n)
1174 var cases []SelectCase
1175 var info []caseInfo
1177 // Ready send.
1178 if x.Maybe() {
1179 ch, val := newop(len(cases), 1)
1180 cases = append(cases, SelectCase{
1181 Dir: SelectSend,
1182 Chan: ch,
1183 Send: val,
1185 info = append(info, caseInfo{desc: "ready send", canSelect: true})
1188 // Ready recv.
1189 if x.Maybe() {
1190 ch, val := newop(len(cases), 1)
1191 ch.Send(val)
1192 cases = append(cases, SelectCase{
1193 Dir: SelectRecv,
1194 Chan: ch,
1196 info = append(info, caseInfo{desc: "ready recv", canSelect: true, recv: val})
1199 // Blocking send.
1200 if x.Maybe() {
1201 ch, val := newop(len(cases), 0)
1202 cases = append(cases, SelectCase{
1203 Dir: SelectSend,
1204 Chan: ch,
1205 Send: val,
1207 // Let it execute?
1208 if x.Maybe() {
1209 f := func() { ch.Recv() }
1210 info = append(info, caseInfo{desc: "blocking send", helper: f})
1211 } else {
1212 info = append(info, caseInfo{desc: "blocking send"})
1216 // Blocking recv.
1217 if x.Maybe() {
1218 ch, val := newop(len(cases), 0)
1219 cases = append(cases, SelectCase{
1220 Dir: SelectRecv,
1221 Chan: ch,
1223 // Let it execute?
1224 if x.Maybe() {
1225 f := func() { ch.Send(val) }
1226 info = append(info, caseInfo{desc: "blocking recv", recv: val, helper: f})
1227 } else {
1228 info = append(info, caseInfo{desc: "blocking recv"})
1232 // Zero Chan send.
1233 if x.Maybe() {
1234 // Maybe include value to send.
1235 var val Value
1236 if x.Maybe() {
1237 val = ValueOf(100)
1239 cases = append(cases, SelectCase{
1240 Dir: SelectSend,
1241 Send: val,
1243 info = append(info, caseInfo{desc: "zero Chan send"})
1246 // Zero Chan receive.
1247 if x.Maybe() {
1248 cases = append(cases, SelectCase{
1249 Dir: SelectRecv,
1251 info = append(info, caseInfo{desc: "zero Chan recv"})
1254 // nil Chan send.
1255 if x.Maybe() {
1256 cases = append(cases, SelectCase{
1257 Dir: SelectSend,
1258 Chan: ValueOf((chan int)(nil)),
1259 Send: ValueOf(101),
1261 info = append(info, caseInfo{desc: "nil Chan send"})
1264 // nil Chan recv.
1265 if x.Maybe() {
1266 cases = append(cases, SelectCase{
1267 Dir: SelectRecv,
1268 Chan: ValueOf((chan int)(nil)),
1270 info = append(info, caseInfo{desc: "nil Chan recv"})
1273 // closed Chan send.
1274 if x.Maybe() {
1275 ch := make(chan int)
1276 close(ch)
1277 cases = append(cases, SelectCase{
1278 Dir: SelectSend,
1279 Chan: ValueOf(ch),
1280 Send: ValueOf(101),
1282 info = append(info, caseInfo{desc: "closed Chan send", canSelect: true, panic: true})
1285 // closed Chan recv.
1286 if x.Maybe() {
1287 ch, val := newop(len(cases), 0)
1288 ch.Close()
1289 val = Zero(val.Type())
1290 cases = append(cases, SelectCase{
1291 Dir: SelectRecv,
1292 Chan: ch,
1294 info = append(info, caseInfo{desc: "closed Chan recv", canSelect: true, closed: true, recv: val})
1297 var helper func() // goroutine to help the select complete
1299 // Add default? Must be last case here, but will permute.
1300 // Add the default if the select would otherwise
1301 // block forever, and maybe add it anyway.
1302 numCanSelect := 0
1303 canProceed := false
1304 canBlock := true
1305 canPanic := false
1306 helpers := []int{}
1307 for i, c := range info {
1308 if c.canSelect {
1309 canProceed = true
1310 canBlock = false
1311 numCanSelect++
1312 if c.panic {
1313 canPanic = true
1315 } else if c.helper != nil {
1316 canProceed = true
1317 helpers = append(helpers, i)
1320 if !canProceed || x.Maybe() {
1321 cases = append(cases, SelectCase{
1322 Dir: SelectDefault,
1324 info = append(info, caseInfo{desc: "default", canSelect: canBlock})
1325 numCanSelect++
1326 } else if canBlock {
1327 // Select needs to communicate with another goroutine.
1328 cas := &info[helpers[x.Choose(len(helpers))]]
1329 helper = cas.helper
1330 cas.canSelect = true
1331 numCanSelect++
1334 // Permute cases and case info.
1335 // Doing too much here makes the exhaustive loop
1336 // too exhausting, so just do two swaps.
1337 for loop := 0; loop < 2; loop++ {
1338 i := x.Choose(len(cases))
1339 j := x.Choose(len(cases))
1340 cases[i], cases[j] = cases[j], cases[i]
1341 info[i], info[j] = info[j], info[i]
1344 if helper != nil {
1345 // We wait before kicking off a goroutine to satisfy a blocked select.
1346 // The pause needs to be big enough to let the select block before
1347 // we run the helper, but if we lose that race once in a while it's okay: the
1348 // select will just proceed immediately. Not a big deal.
1349 // For short tests we can grow [sic] the timeout a bit without fear of taking too long
1350 pause := 10 * time.Microsecond
1351 if testing.Short() {
1352 pause = 100 * time.Microsecond
1354 time.AfterFunc(pause, helper)
1357 // Run select.
1358 i, recv, recvOK, panicErr := runSelect(cases, info)
1359 if panicErr != nil && !canPanic {
1360 t.Fatalf("%s\npanicked unexpectedly: %v", fmtSelect(info), panicErr)
1362 if panicErr == nil && canPanic && numCanSelect == 1 {
1363 t.Fatalf("%s\nselected #%d incorrectly (should panic)", fmtSelect(info), i)
1365 if panicErr != nil {
1366 continue
1369 cas := info[i]
1370 if !cas.canSelect {
1371 recvStr := ""
1372 if recv.IsValid() {
1373 recvStr = fmt.Sprintf(", received %v, %v", recv.Interface(), recvOK)
1375 t.Fatalf("%s\nselected #%d incorrectly%s", fmtSelect(info), i, recvStr)
1376 continue
1378 if cas.panic {
1379 t.Fatalf("%s\nselected #%d incorrectly (case should panic)", fmtSelect(info), i)
1380 continue
1383 if cases[i].Dir == SelectRecv {
1384 if !recv.IsValid() {
1385 t.Fatalf("%s\nselected #%d but got %v, %v, want %v, %v", fmtSelect(info), i, recv, recvOK, cas.recv.Interface(), !cas.closed)
1387 if !cas.recv.IsValid() {
1388 t.Fatalf("%s\nselected #%d but internal error: missing recv value", fmtSelect(info), i)
1390 if recv.Interface() != cas.recv.Interface() || recvOK != !cas.closed {
1391 if recv.Interface() == cas.recv.Interface() && recvOK == !cas.closed {
1392 t.Fatalf("%s\nselected #%d, got %#v, %v, and DeepEqual is broken on %T", fmtSelect(info), i, recv.Interface(), recvOK, recv.Interface())
1394 t.Fatalf("%s\nselected #%d but got %#v, %v, want %#v, %v", fmtSelect(info), i, recv.Interface(), recvOK, cas.recv.Interface(), !cas.closed)
1396 } else {
1397 if recv.IsValid() || recvOK {
1398 t.Fatalf("%s\nselected #%d but got %v, %v, want %v, %v", fmtSelect(info), i, recv, recvOK, Value{}, false)
1404 // selectWatch and the selectWatcher are a watchdog mechanism for running Select.
1405 // If the selectWatcher notices that the select has been blocked for >1 second, it prints
1406 // an error describing the select and panics the entire test binary.
1407 var selectWatch struct {
1408 sync.Mutex
1409 once sync.Once
1410 now time.Time
1411 info []caseInfo
1414 func selectWatcher() {
1415 for {
1416 time.Sleep(1 * time.Second)
1417 selectWatch.Lock()
1418 if selectWatch.info != nil && time.Since(selectWatch.now) > 10*time.Second {
1419 fmt.Fprintf(os.Stderr, "TestSelect:\n%s blocked indefinitely\n", fmtSelect(selectWatch.info))
1420 panic("select stuck")
1422 selectWatch.Unlock()
1426 // runSelect runs a single select test.
1427 // It returns the values returned by Select but also returns
1428 // a panic value if the Select panics.
1429 func runSelect(cases []SelectCase, info []caseInfo) (chosen int, recv Value, recvOK bool, panicErr interface{}) {
1430 defer func() {
1431 panicErr = recover()
1433 selectWatch.Lock()
1434 selectWatch.info = nil
1435 selectWatch.Unlock()
1438 selectWatch.Lock()
1439 selectWatch.now = time.Now()
1440 selectWatch.info = info
1441 selectWatch.Unlock()
1443 chosen, recv, recvOK = Select(cases)
1444 return
1447 // fmtSelect formats the information about a single select test.
1448 func fmtSelect(info []caseInfo) string {
1449 var buf bytes.Buffer
1450 fmt.Fprintf(&buf, "\nselect {\n")
1451 for i, cas := range info {
1452 fmt.Fprintf(&buf, "%d: %s", i, cas.desc)
1453 if cas.recv.IsValid() {
1454 fmt.Fprintf(&buf, " val=%#v", cas.recv.Interface())
1456 if cas.canSelect {
1457 fmt.Fprintf(&buf, " canselect")
1459 if cas.panic {
1460 fmt.Fprintf(&buf, " panic")
1462 fmt.Fprintf(&buf, "\n")
1464 fmt.Fprintf(&buf, "}")
1465 return buf.String()
1468 type two [2]uintptr
1470 // Difficult test for function call because of
1471 // implicit padding between arguments.
1472 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) {
1473 return b, c, d, e, f, g, h
1476 func TestFunc(t *testing.T) {
1477 ret := ValueOf(dummy).Call([]Value{
1478 ValueOf(byte(10)),
1479 ValueOf(20),
1480 ValueOf(byte(30)),
1481 ValueOf(two{40, 50}),
1482 ValueOf(byte(60)),
1483 ValueOf(float32(70)),
1484 ValueOf(byte(80)),
1486 if len(ret) != 7 {
1487 t.Fatalf("Call returned %d values, want 7", len(ret))
1490 i := byte(ret[0].Uint())
1491 j := int(ret[1].Int())
1492 k := byte(ret[2].Uint())
1493 l := ret[3].Interface().(two)
1494 m := byte(ret[4].Uint())
1495 n := float32(ret[5].Float())
1496 o := byte(ret[6].Uint())
1498 if i != 10 || j != 20 || k != 30 || l != (two{40, 50}) || m != 60 || n != 70 || o != 80 {
1499 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)
1502 for i, v := range ret {
1503 if v.CanAddr() {
1504 t.Errorf("result %d is addressable", i)
1509 type emptyStruct struct{}
1511 type nonEmptyStruct struct {
1512 member int
1515 func returnEmpty() emptyStruct {
1516 return emptyStruct{}
1519 func takesEmpty(e emptyStruct) {
1522 func returnNonEmpty(i int) nonEmptyStruct {
1523 return nonEmptyStruct{member: i}
1526 func takesNonEmpty(n nonEmptyStruct) int {
1527 return n.member
1530 func TestCallWithStruct(t *testing.T) {
1531 r := ValueOf(returnEmpty).Call(nil)
1532 if len(r) != 1 || r[0].Type() != TypeOf(emptyStruct{}) {
1533 t.Errorf("returning empty struct returned %#v instead", r)
1535 r = ValueOf(takesEmpty).Call([]Value{ValueOf(emptyStruct{})})
1536 if len(r) != 0 {
1537 t.Errorf("takesEmpty returned values: %#v", r)
1539 r = ValueOf(returnNonEmpty).Call([]Value{ValueOf(42)})
1540 if len(r) != 1 || r[0].Type() != TypeOf(nonEmptyStruct{}) || r[0].Field(0).Int() != 42 {
1541 t.Errorf("returnNonEmpty returned %#v", r)
1543 r = ValueOf(takesNonEmpty).Call([]Value{ValueOf(nonEmptyStruct{member: 42})})
1544 if len(r) != 1 || r[0].Type() != TypeOf(1) || r[0].Int() != 42 {
1545 t.Errorf("takesNonEmpty returned %#v", r)
1549 func BenchmarkCall(b *testing.B) {
1550 fv := ValueOf(func(a, b string) {})
1551 b.ReportAllocs()
1552 b.RunParallel(func(pb *testing.PB) {
1553 args := []Value{ValueOf("a"), ValueOf("b")}
1554 for pb.Next() {
1555 fv.Call(args)
1560 func BenchmarkCallArgCopy(b *testing.B) {
1561 byteArray := func(n int) Value {
1562 return Zero(ArrayOf(n, TypeOf(byte(0))))
1564 sizes := [...]struct {
1565 fv Value
1566 arg Value
1568 {ValueOf(func(a [128]byte) {}), byteArray(128)},
1569 {ValueOf(func(a [256]byte) {}), byteArray(256)},
1570 {ValueOf(func(a [1024]byte) {}), byteArray(1024)},
1571 {ValueOf(func(a [4096]byte) {}), byteArray(4096)},
1572 {ValueOf(func(a [65536]byte) {}), byteArray(65536)},
1574 for _, size := range sizes {
1575 bench := func(b *testing.B) {
1576 args := []Value{size.arg}
1577 b.SetBytes(int64(size.arg.Len()))
1578 b.ResetTimer()
1579 for i := 0; i < b.N; i++ {
1580 size.fv.Call(args)
1583 name := fmt.Sprintf("size=%v", size.arg.Len())
1584 b.Run(name, bench)
1588 func TestMakeFunc(t *testing.T) {
1589 f := dummy
1590 fv := MakeFunc(TypeOf(f), func(in []Value) []Value { return in })
1591 ValueOf(&f).Elem().Set(fv)
1593 // Call g with small arguments so that there is
1594 // something predictable (and different from the
1595 // correct results) in those positions on the stack.
1596 g := dummy
1597 g(1, 2, 3, two{4, 5}, 6, 7, 8)
1599 // Call constructed function f.
1600 i, j, k, l, m, n, o := f(10, 20, 30, two{40, 50}, 60, 70, 80)
1601 if i != 10 || j != 20 || k != 30 || l != (two{40, 50}) || m != 60 || n != 70 || o != 80 {
1602 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)
1606 func TestMakeFuncInterface(t *testing.T) {
1607 fn := func(i int) int { return i }
1608 incr := func(in []Value) []Value {
1609 return []Value{ValueOf(int(in[0].Int() + 1))}
1611 fv := MakeFunc(TypeOf(fn), incr)
1612 ValueOf(&fn).Elem().Set(fv)
1613 if r := fn(2); r != 3 {
1614 t.Errorf("Call returned %d, want 3", r)
1616 if r := fv.Call([]Value{ValueOf(14)})[0].Int(); r != 15 {
1617 t.Errorf("Call returned %d, want 15", r)
1619 if r := fv.Interface().(func(int) int)(26); r != 27 {
1620 t.Errorf("Call returned %d, want 27", r)
1624 func TestMakeFuncVariadic(t *testing.T) {
1625 // Test that variadic arguments are packed into a slice and passed as last arg
1626 fn := func(_ int, is ...int) []int { return nil }
1627 fv := MakeFunc(TypeOf(fn), func(in []Value) []Value { return in[1:2] })
1628 ValueOf(&fn).Elem().Set(fv)
1630 r := fn(1, 2, 3)
1631 if r[0] != 2 || r[1] != 3 {
1632 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
1635 r = fn(1, []int{2, 3}...)
1636 if r[0] != 2 || r[1] != 3 {
1637 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
1640 r = fv.Call([]Value{ValueOf(1), ValueOf(2), ValueOf(3)})[0].Interface().([]int)
1641 if r[0] != 2 || r[1] != 3 {
1642 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
1645 r = fv.CallSlice([]Value{ValueOf(1), ValueOf([]int{2, 3})})[0].Interface().([]int)
1646 if r[0] != 2 || r[1] != 3 {
1647 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
1650 f := fv.Interface().(func(int, ...int) []int)
1652 r = f(1, 2, 3)
1653 if r[0] != 2 || r[1] != 3 {
1654 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
1656 r = f(1, []int{2, 3}...)
1657 if r[0] != 2 || r[1] != 3 {
1658 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
1662 type Point struct {
1663 x, y int
1666 // This will be index 0.
1667 func (p Point) AnotherMethod(scale int) int {
1668 return -1
1671 // This will be index 1.
1672 func (p Point) Dist(scale int) int {
1673 //println("Point.Dist", p.x, p.y, scale)
1674 return p.x*p.x*scale + p.y*p.y*scale
1677 // This will be index 2.
1678 func (p Point) GCMethod(k int) int {
1679 runtime.GC()
1680 return k + p.x
1683 // This will be index 3.
1684 func (p Point) TotalDist(points ...Point) int {
1685 tot := 0
1686 for _, q := range points {
1687 dx := q.x - p.x
1688 dy := q.y - p.y
1689 tot += dx*dx + dy*dy // Should call Sqrt, but it's just a test.
1692 return tot
1695 func TestMethod(t *testing.T) {
1696 // Non-curried method of type.
1697 p := Point{3, 4}
1698 i := TypeOf(p).Method(1).Func.Call([]Value{ValueOf(p), ValueOf(10)})[0].Int()
1699 if i != 250 {
1700 t.Errorf("Type Method returned %d; want 250", i)
1703 m, ok := TypeOf(p).MethodByName("Dist")
1704 if !ok {
1705 t.Fatalf("method by name failed")
1707 i = m.Func.Call([]Value{ValueOf(p), ValueOf(11)})[0].Int()
1708 if i != 275 {
1709 t.Errorf("Type MethodByName returned %d; want 275", i)
1712 i = TypeOf(&p).Method(1).Func.Call([]Value{ValueOf(&p), ValueOf(12)})[0].Int()
1713 if i != 300 {
1714 t.Errorf("Pointer Type Method returned %d; want 300", i)
1717 m, ok = TypeOf(&p).MethodByName("Dist")
1718 if !ok {
1719 t.Fatalf("ptr method by name failed")
1721 i = m.Func.Call([]Value{ValueOf(&p), ValueOf(13)})[0].Int()
1722 if i != 325 {
1723 t.Errorf("Pointer Type MethodByName returned %d; want 325", i)
1726 // Curried method of value.
1727 tfunc := TypeOf((func(int) int)(nil))
1728 v := ValueOf(p).Method(1)
1729 if tt := v.Type(); tt != tfunc {
1730 t.Errorf("Value Method Type is %s; want %s", tt, tfunc)
1732 i = v.Call([]Value{ValueOf(14)})[0].Int()
1733 if i != 350 {
1734 t.Errorf("Value Method returned %d; want 350", i)
1736 v = ValueOf(p).MethodByName("Dist")
1737 if tt := v.Type(); tt != tfunc {
1738 t.Errorf("Value MethodByName Type is %s; want %s", tt, tfunc)
1740 i = v.Call([]Value{ValueOf(15)})[0].Int()
1741 if i != 375 {
1742 t.Errorf("Value MethodByName returned %d; want 375", i)
1745 // Curried method of pointer.
1746 v = ValueOf(&p).Method(1)
1747 if tt := v.Type(); tt != tfunc {
1748 t.Errorf("Pointer Value Method Type is %s; want %s", tt, tfunc)
1750 i = v.Call([]Value{ValueOf(16)})[0].Int()
1751 if i != 400 {
1752 t.Errorf("Pointer Value Method returned %d; want 400", i)
1754 v = ValueOf(&p).MethodByName("Dist")
1755 if tt := v.Type(); tt != tfunc {
1756 t.Errorf("Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
1758 i = v.Call([]Value{ValueOf(17)})[0].Int()
1759 if i != 425 {
1760 t.Errorf("Pointer Value MethodByName returned %d; want 425", i)
1763 // Curried method of interface value.
1764 // Have to wrap interface value in a struct to get at it.
1765 // Passing it to ValueOf directly would
1766 // access the underlying Point, not the interface.
1767 var x interface {
1768 Dist(int) int
1769 } = p
1770 pv := ValueOf(&x).Elem()
1771 v = pv.Method(0)
1772 if tt := v.Type(); tt != tfunc {
1773 t.Errorf("Interface Method Type is %s; want %s", tt, tfunc)
1775 i = v.Call([]Value{ValueOf(18)})[0].Int()
1776 if i != 450 {
1777 t.Errorf("Interface Method returned %d; want 450", i)
1779 v = pv.MethodByName("Dist")
1780 if tt := v.Type(); tt != tfunc {
1781 t.Errorf("Interface MethodByName Type is %s; want %s", tt, tfunc)
1783 i = v.Call([]Value{ValueOf(19)})[0].Int()
1784 if i != 475 {
1785 t.Errorf("Interface MethodByName returned %d; want 475", i)
1789 func TestMethodValue(t *testing.T) {
1790 p := Point{3, 4}
1791 var i int64
1793 // Curried method of value.
1794 tfunc := TypeOf((func(int) int)(nil))
1795 v := ValueOf(p).Method(1)
1796 if tt := v.Type(); tt != tfunc {
1797 t.Errorf("Value Method Type is %s; want %s", tt, tfunc)
1799 i = ValueOf(v.Interface()).Call([]Value{ValueOf(10)})[0].Int()
1800 if i != 250 {
1801 t.Errorf("Value Method returned %d; want 250", i)
1803 v = ValueOf(p).MethodByName("Dist")
1804 if tt := v.Type(); tt != tfunc {
1805 t.Errorf("Value MethodByName Type is %s; want %s", tt, tfunc)
1807 i = ValueOf(v.Interface()).Call([]Value{ValueOf(11)})[0].Int()
1808 if i != 275 {
1809 t.Errorf("Value MethodByName returned %d; want 275", i)
1812 // Curried method of pointer.
1813 v = ValueOf(&p).Method(1)
1814 if tt := v.Type(); tt != tfunc {
1815 t.Errorf("Pointer Value Method Type is %s; want %s", tt, tfunc)
1817 i = ValueOf(v.Interface()).Call([]Value{ValueOf(12)})[0].Int()
1818 if i != 300 {
1819 t.Errorf("Pointer Value Method returned %d; want 300", i)
1821 v = ValueOf(&p).MethodByName("Dist")
1822 if tt := v.Type(); tt != tfunc {
1823 t.Errorf("Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
1825 i = ValueOf(v.Interface()).Call([]Value{ValueOf(13)})[0].Int()
1826 if i != 325 {
1827 t.Errorf("Pointer Value MethodByName returned %d; want 325", i)
1830 // Curried method of pointer to pointer.
1831 pp := &p
1832 v = ValueOf(&pp).Elem().Method(1)
1833 if tt := v.Type(); tt != tfunc {
1834 t.Errorf("Pointer Pointer Value Method Type is %s; want %s", tt, tfunc)
1836 i = ValueOf(v.Interface()).Call([]Value{ValueOf(14)})[0].Int()
1837 if i != 350 {
1838 t.Errorf("Pointer Pointer Value Method returned %d; want 350", i)
1840 v = ValueOf(&pp).Elem().MethodByName("Dist")
1841 if tt := v.Type(); tt != tfunc {
1842 t.Errorf("Pointer Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
1844 i = ValueOf(v.Interface()).Call([]Value{ValueOf(15)})[0].Int()
1845 if i != 375 {
1846 t.Errorf("Pointer Pointer Value MethodByName returned %d; want 375", i)
1849 // Curried method of interface value.
1850 // Have to wrap interface value in a struct to get at it.
1851 // Passing it to ValueOf directly would
1852 // access the underlying Point, not the interface.
1853 var s = struct {
1854 X interface {
1855 Dist(int) int
1857 }{p}
1858 pv := ValueOf(s).Field(0)
1859 v = pv.Method(0)
1860 if tt := v.Type(); tt != tfunc {
1861 t.Errorf("Interface Method Type is %s; want %s", tt, tfunc)
1863 i = ValueOf(v.Interface()).Call([]Value{ValueOf(16)})[0].Int()
1864 if i != 400 {
1865 t.Errorf("Interface Method returned %d; want 400", i)
1867 v = pv.MethodByName("Dist")
1868 if tt := v.Type(); tt != tfunc {
1869 t.Errorf("Interface MethodByName Type is %s; want %s", tt, tfunc)
1871 i = ValueOf(v.Interface()).Call([]Value{ValueOf(17)})[0].Int()
1872 if i != 425 {
1873 t.Errorf("Interface MethodByName returned %d; want 425", i)
1877 func TestVariadicMethodValue(t *testing.T) {
1878 p := Point{3, 4}
1879 points := []Point{{20, 21}, {22, 23}, {24, 25}}
1880 want := int64(p.TotalDist(points[0], points[1], points[2]))
1882 // Curried method of value.
1883 tfunc := TypeOf((func(...Point) int)(nil))
1884 v := ValueOf(p).Method(3)
1885 if tt := v.Type(); tt != tfunc {
1886 t.Errorf("Variadic Method Type is %s; want %s", tt, tfunc)
1888 i := ValueOf(v.Interface()).Call([]Value{ValueOf(points[0]), ValueOf(points[1]), ValueOf(points[2])})[0].Int()
1889 if i != want {
1890 t.Errorf("Variadic Method returned %d; want %d", i, want)
1892 i = ValueOf(v.Interface()).CallSlice([]Value{ValueOf(points)})[0].Int()
1893 if i != want {
1894 t.Errorf("Variadic Method CallSlice returned %d; want %d", i, want)
1897 f := v.Interface().(func(...Point) int)
1898 i = int64(f(points[0], points[1], points[2]))
1899 if i != want {
1900 t.Errorf("Variadic Method Interface returned %d; want %d", i, want)
1902 i = int64(f(points...))
1903 if i != want {
1904 t.Errorf("Variadic Method Interface Slice returned %d; want %d", i, want)
1908 // Reflect version of $GOROOT/test/method5.go
1910 // Concrete types implementing M method.
1911 // Smaller than a word, word-sized, larger than a word.
1912 // Value and pointer receivers.
1914 type Tinter interface {
1915 M(int, byte) (byte, int)
1918 type Tsmallv byte
1920 func (v Tsmallv) M(x int, b byte) (byte, int) { return b, x + int(v) }
1922 type Tsmallp byte
1924 func (p *Tsmallp) M(x int, b byte) (byte, int) { return b, x + int(*p) }
1926 type Twordv uintptr
1928 func (v Twordv) M(x int, b byte) (byte, int) { return b, x + int(v) }
1930 type Twordp uintptr
1932 func (p *Twordp) M(x int, b byte) (byte, int) { return b, x + int(*p) }
1934 type Tbigv [2]uintptr
1936 func (v Tbigv) M(x int, b byte) (byte, int) { return b, x + int(v[0]) + int(v[1]) }
1938 type Tbigp [2]uintptr
1940 func (p *Tbigp) M(x int, b byte) (byte, int) { return b, x + int(p[0]) + int(p[1]) }
1942 type tinter interface {
1943 m(int, byte) (byte, int)
1946 // Embedding via pointer.
1948 type Tm1 struct {
1952 type Tm2 struct {
1953 *Tm3
1956 type Tm3 struct {
1957 *Tm4
1960 type Tm4 struct {
1963 func (t4 Tm4) M(x int, b byte) (byte, int) { return b, x + 40 }
1965 func TestMethod5(t *testing.T) {
1966 CheckF := func(name string, f func(int, byte) (byte, int), inc int) {
1967 b, x := f(1000, 99)
1968 if b != 99 || x != 1000+inc {
1969 t.Errorf("%s(1000, 99) = %v, %v, want 99, %v", name, b, x, 1000+inc)
1973 CheckV := func(name string, i Value, inc int) {
1974 bx := i.Method(0).Call([]Value{ValueOf(1000), ValueOf(byte(99))})
1975 b := bx[0].Interface()
1976 x := bx[1].Interface()
1977 if b != byte(99) || x != 1000+inc {
1978 t.Errorf("direct %s.M(1000, 99) = %v, %v, want 99, %v", name, b, x, 1000+inc)
1981 CheckF(name+".M", i.Method(0).Interface().(func(int, byte) (byte, int)), inc)
1984 var TinterType = TypeOf(new(Tinter)).Elem()
1986 CheckI := func(name string, i interface{}, inc int) {
1987 v := ValueOf(i)
1988 CheckV(name, v, inc)
1989 CheckV("(i="+name+")", v.Convert(TinterType), inc)
1992 sv := Tsmallv(1)
1993 CheckI("sv", sv, 1)
1994 CheckI("&sv", &sv, 1)
1996 sp := Tsmallp(2)
1997 CheckI("&sp", &sp, 2)
1999 wv := Twordv(3)
2000 CheckI("wv", wv, 3)
2001 CheckI("&wv", &wv, 3)
2003 wp := Twordp(4)
2004 CheckI("&wp", &wp, 4)
2006 bv := Tbigv([2]uintptr{5, 6})
2007 CheckI("bv", bv, 11)
2008 CheckI("&bv", &bv, 11)
2010 bp := Tbigp([2]uintptr{7, 8})
2011 CheckI("&bp", &bp, 15)
2013 t4 := Tm4{}
2014 t3 := Tm3{&t4}
2015 t2 := Tm2{&t3}
2016 t1 := Tm1{t2}
2017 CheckI("t4", t4, 40)
2018 CheckI("&t4", &t4, 40)
2019 CheckI("t3", t3, 40)
2020 CheckI("&t3", &t3, 40)
2021 CheckI("t2", t2, 40)
2022 CheckI("&t2", &t2, 40)
2023 CheckI("t1", t1, 40)
2024 CheckI("&t1", &t1, 40)
2026 var tnil Tinter
2027 vnil := ValueOf(&tnil).Elem()
2028 shouldPanic(func() { vnil.Method(0) })
2031 func TestInterfaceSet(t *testing.T) {
2032 p := &Point{3, 4}
2034 var s struct {
2035 I interface{}
2036 P interface {
2037 Dist(int) int
2040 sv := ValueOf(&s).Elem()
2041 sv.Field(0).Set(ValueOf(p))
2042 if q := s.I.(*Point); q != p {
2043 t.Errorf("i: have %p want %p", q, p)
2046 pv := sv.Field(1)
2047 pv.Set(ValueOf(p))
2048 if q := s.P.(*Point); q != p {
2049 t.Errorf("i: have %p want %p", q, p)
2052 i := pv.Method(0).Call([]Value{ValueOf(10)})[0].Int()
2053 if i != 250 {
2054 t.Errorf("Interface Method returned %d; want 250", i)
2058 type T1 struct {
2059 a string
2063 func TestAnonymousFields(t *testing.T) {
2064 var field StructField
2065 var ok bool
2066 var t1 T1
2067 type1 := TypeOf(t1)
2068 if field, ok = type1.FieldByName("int"); !ok {
2069 t.Fatal("no field 'int'")
2071 if field.Index[0] != 1 {
2072 t.Error("field index should be 1; is", field.Index)
2076 type FTest struct {
2077 s interface{}
2078 name string
2079 index []int
2080 value int
2083 type D1 struct {
2084 d int
2086 type D2 struct {
2087 d int
2090 type S0 struct {
2091 A, B, C int
2096 type S1 struct {
2097 B int
2101 type S2 struct {
2102 A int
2106 type S1x struct {
2110 type S1y struct {
2114 type S3 struct {
2117 D, E int
2118 *S1y
2121 type S4 struct {
2123 A int
2126 // The X in S6 and S7 annihilate, but they also block the X in S8.S9.
2127 type S5 struct {
2133 type S6 struct {
2134 X int
2137 type S7 S6
2139 type S8 struct {
2143 type S9 struct {
2144 X int
2145 Y int
2148 // The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
2149 type S10 struct {
2155 type S11 struct {
2159 type S12 struct {
2163 type S13 struct {
2167 // The X in S15.S11.S1 and S16.S11.S1 annihilate.
2168 type S14 struct {
2173 type S15 struct {
2177 type S16 struct {
2181 var fieldTests = []FTest{
2182 {struct{}{}, "", nil, 0},
2183 {struct{}{}, "Foo", nil, 0},
2184 {S0{A: 'a'}, "A", []int{0}, 'a'},
2185 {S0{}, "D", nil, 0},
2186 {S1{S0: S0{A: 'a'}}, "A", []int{1, 0}, 'a'},
2187 {S1{B: 'b'}, "B", []int{0}, 'b'},
2188 {S1{}, "S0", []int{1}, 0},
2189 {S1{S0: S0{C: 'c'}}, "C", []int{1, 2}, 'c'},
2190 {S2{A: 'a'}, "A", []int{0}, 'a'},
2191 {S2{}, "S1", []int{1}, 0},
2192 {S2{S1: &S1{B: 'b'}}, "B", []int{1, 0}, 'b'},
2193 {S2{S1: &S1{S0: S0{C: 'c'}}}, "C", []int{1, 1, 2}, 'c'},
2194 {S2{}, "D", nil, 0},
2195 {S3{}, "S1", nil, 0},
2196 {S3{S2: S2{A: 'a'}}, "A", []int{1, 0}, 'a'},
2197 {S3{}, "B", nil, 0},
2198 {S3{D: 'd'}, "D", []int{2}, 0},
2199 {S3{E: 'e'}, "E", []int{3}, 'e'},
2200 {S4{A: 'a'}, "A", []int{1}, 'a'},
2201 {S4{}, "B", nil, 0},
2202 {S5{}, "X", nil, 0},
2203 {S5{}, "Y", []int{2, 0, 1}, 0},
2204 {S10{}, "X", nil, 0},
2205 {S10{}, "Y", []int{2, 0, 0, 1}, 0},
2206 {S14{}, "X", nil, 0},
2209 func TestFieldByIndex(t *testing.T) {
2210 for _, test := range fieldTests {
2211 s := TypeOf(test.s)
2212 f := s.FieldByIndex(test.index)
2213 if f.Name != "" {
2214 if test.index != nil {
2215 if f.Name != test.name {
2216 t.Errorf("%s.%s found; want %s", s.Name(), f.Name, test.name)
2218 } else {
2219 t.Errorf("%s.%s found", s.Name(), f.Name)
2221 } else if len(test.index) > 0 {
2222 t.Errorf("%s.%s not found", s.Name(), test.name)
2225 if test.value != 0 {
2226 v := ValueOf(test.s).FieldByIndex(test.index)
2227 if v.IsValid() {
2228 if x, ok := v.Interface().(int); ok {
2229 if x != test.value {
2230 t.Errorf("%s%v is %d; want %d", s.Name(), test.index, x, test.value)
2232 } else {
2233 t.Errorf("%s%v value not an int", s.Name(), test.index)
2235 } else {
2236 t.Errorf("%s%v value not found", s.Name(), test.index)
2242 func TestFieldByName(t *testing.T) {
2243 for _, test := range fieldTests {
2244 s := TypeOf(test.s)
2245 f, found := s.FieldByName(test.name)
2246 if found {
2247 if test.index != nil {
2248 // Verify field depth and index.
2249 if len(f.Index) != len(test.index) {
2250 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)
2251 } else {
2252 for i, x := range f.Index {
2253 if x != test.index[i] {
2254 t.Errorf("%s.%s.Index[%d] is %d; want %d", s.Name(), test.name, i, x, test.index[i])
2258 } else {
2259 t.Errorf("%s.%s found", s.Name(), f.Name)
2261 } else if len(test.index) > 0 {
2262 t.Errorf("%s.%s not found", s.Name(), test.name)
2265 if test.value != 0 {
2266 v := ValueOf(test.s).FieldByName(test.name)
2267 if v.IsValid() {
2268 if x, ok := v.Interface().(int); ok {
2269 if x != test.value {
2270 t.Errorf("%s.%s is %d; want %d", s.Name(), test.name, x, test.value)
2272 } else {
2273 t.Errorf("%s.%s value not an int", s.Name(), test.name)
2275 } else {
2276 t.Errorf("%s.%s value not found", s.Name(), test.name)
2282 func TestImportPath(t *testing.T) {
2283 tests := []struct {
2284 t Type
2285 path string
2287 {TypeOf(&base64.Encoding{}).Elem(), "encoding/base64"},
2288 {TypeOf(int(0)), ""},
2289 {TypeOf(int8(0)), ""},
2290 {TypeOf(int16(0)), ""},
2291 {TypeOf(int32(0)), ""},
2292 {TypeOf(int64(0)), ""},
2293 {TypeOf(uint(0)), ""},
2294 {TypeOf(uint8(0)), ""},
2295 {TypeOf(uint16(0)), ""},
2296 {TypeOf(uint32(0)), ""},
2297 {TypeOf(uint64(0)), ""},
2298 {TypeOf(uintptr(0)), ""},
2299 {TypeOf(float32(0)), ""},
2300 {TypeOf(float64(0)), ""},
2301 {TypeOf(complex64(0)), ""},
2302 {TypeOf(complex128(0)), ""},
2303 {TypeOf(byte(0)), ""},
2304 {TypeOf(rune(0)), ""},
2305 {TypeOf([]byte(nil)), ""},
2306 {TypeOf([]rune(nil)), ""},
2307 {TypeOf(string("")), ""},
2308 {TypeOf((*interface{})(nil)).Elem(), ""},
2309 {TypeOf((*byte)(nil)), ""},
2310 {TypeOf((*rune)(nil)), ""},
2311 {TypeOf((*int64)(nil)), ""},
2312 {TypeOf(map[string]int{}), ""},
2313 {TypeOf((*error)(nil)).Elem(), ""},
2314 {TypeOf((*Point)(nil)), ""},
2315 {TypeOf((*Point)(nil)).Elem(), "reflect_test"},
2317 for _, test := range tests {
2318 if path := test.t.PkgPath(); path != test.path {
2319 t.Errorf("%v.PkgPath() = %q, want %q", test.t, path, test.path)
2324 func TestFieldPkgPath(t *testing.T) {
2325 typ := TypeOf(struct {
2326 Exported string
2327 unexported string
2328 OtherPkgFields
2329 }{})
2331 type pkgpathTest struct {
2332 index []int
2333 pkgPath string
2334 anonymous bool
2337 checkPkgPath := func(name string, s []pkgpathTest) {
2338 for _, test := range s {
2339 f := typ.FieldByIndex(test.index)
2340 if got, want := f.PkgPath, test.pkgPath; got != want {
2341 t.Errorf("%s: Field(%d).PkgPath = %q, want %q", name, test.index, got, want)
2343 if got, want := f.Anonymous, test.anonymous; got != want {
2344 t.Errorf("%s: Field(%d).Anonymous = %v, want %v", name, test.index, got, want)
2349 checkPkgPath("testStruct", []pkgpathTest{
2350 {[]int{0}, "", false}, // Exported
2351 {[]int{1}, "reflect_test", false}, // unexported
2352 {[]int{2}, "", true}, // OtherPkgFields
2353 {[]int{2, 0}, "", false}, // OtherExported
2354 {[]int{2, 1}, "reflect", false}, // otherUnexported
2357 type localOtherPkgFields OtherPkgFields
2358 typ = TypeOf(localOtherPkgFields{})
2359 checkPkgPath("localOtherPkgFields", []pkgpathTest{
2360 {[]int{0}, "", false}, // OtherExported
2361 {[]int{1}, "reflect", false}, // otherUnexported
2365 func TestVariadicType(t *testing.T) {
2366 // Test example from Type documentation.
2367 var f func(x int, y ...float64)
2368 typ := TypeOf(f)
2369 if typ.NumIn() == 2 && typ.In(0) == TypeOf(int(0)) {
2370 sl := typ.In(1)
2371 if sl.Kind() == Slice {
2372 if sl.Elem() == TypeOf(0.0) {
2373 // ok
2374 return
2379 // Failed
2380 t.Errorf("want NumIn() = 2, In(0) = int, In(1) = []float64")
2381 s := fmt.Sprintf("have NumIn() = %d", typ.NumIn())
2382 for i := 0; i < typ.NumIn(); i++ {
2383 s += fmt.Sprintf(", In(%d) = %s", i, typ.In(i))
2385 t.Error(s)
2388 type inner struct {
2389 x int
2392 type outer struct {
2393 y int
2394 inner
2397 func (*inner) M() {}
2398 func (*outer) M() {}
2400 func TestNestedMethods(t *testing.T) {
2401 t.Skip("fails on gccgo due to function wrappers")
2402 typ := TypeOf((*outer)(nil))
2403 if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != ValueOf((*outer).M).Pointer() {
2404 t.Errorf("Wrong method table for outer: (M=%p)", (*outer).M)
2405 for i := 0; i < typ.NumMethod(); i++ {
2406 m := typ.Method(i)
2407 t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer())
2412 type unexp struct{}
2414 func (*unexp) f() (int32, int8) { return 7, 7 }
2415 func (*unexp) g() (int64, int8) { return 8, 8 }
2417 type unexpI interface {
2418 f() (int32, int8)
2421 var unexpi unexpI = new(unexp)
2423 func TestUnexportedMethods(t *testing.T) {
2424 typ := TypeOf(unexpi)
2426 if got := typ.NumMethod(); got != 0 {
2427 t.Errorf("NumMethod=%d, want 0 satisfied methods", got)
2431 type InnerInt struct {
2432 X int
2435 type OuterInt struct {
2436 Y int
2437 InnerInt
2440 func (i *InnerInt) M() int {
2441 return i.X
2444 func TestEmbeddedMethods(t *testing.T) {
2445 /* This part of the test fails on gccgo due to function wrappers.
2446 typ := TypeOf((*OuterInt)(nil))
2447 if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != ValueOf((*OuterInt).M).Pointer() {
2448 t.Errorf("Wrong method table for OuterInt: (m=%p)", (*OuterInt).M)
2449 for i := 0; i < typ.NumMethod(); i++ {
2450 m := typ.Method(i)
2451 t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer())
2456 i := &InnerInt{3}
2457 if v := ValueOf(i).Method(0).Call(nil)[0].Int(); v != 3 {
2458 t.Errorf("i.M() = %d, want 3", v)
2461 o := &OuterInt{1, InnerInt{2}}
2462 if v := ValueOf(o).Method(0).Call(nil)[0].Int(); v != 2 {
2463 t.Errorf("i.M() = %d, want 2", v)
2466 f := (*OuterInt).M
2467 if v := f(o); v != 2 {
2468 t.Errorf("f(o) = %d, want 2", v)
2472 type FuncDDD func(...interface{}) error
2474 func (f FuncDDD) M() {}
2476 func TestNumMethodOnDDD(t *testing.T) {
2477 rv := ValueOf((FuncDDD)(nil))
2478 if n := rv.NumMethod(); n != 1 {
2479 t.Fatalf("NumMethod()=%d, want 1", n)
2483 func TestPtrTo(t *testing.T) {
2484 // This block of code means that the ptrToThis field of the
2485 // reflect data for *unsafe.Pointer is non zero, see
2486 // https://golang.org/issue/19003
2487 var x unsafe.Pointer
2488 var y = &x
2489 var z = &y
2491 var i int
2493 typ := TypeOf(z)
2494 for i = 0; i < 100; i++ {
2495 typ = PtrTo(typ)
2497 for i = 0; i < 100; i++ {
2498 typ = typ.Elem()
2500 if typ != TypeOf(z) {
2501 t.Errorf("after 100 PtrTo and Elem, have %s, want %s", typ, TypeOf(z))
2505 func TestPtrToGC(t *testing.T) {
2506 type T *uintptr
2507 tt := TypeOf(T(nil))
2508 pt := PtrTo(tt)
2509 const n = 100
2510 var x []interface{}
2511 for i := 0; i < n; i++ {
2512 v := New(pt)
2513 p := new(*uintptr)
2514 *p = new(uintptr)
2515 **p = uintptr(i)
2516 v.Elem().Set(ValueOf(p).Convert(pt))
2517 x = append(x, v.Interface())
2519 runtime.GC()
2521 for i, xi := range x {
2522 k := ValueOf(xi).Elem().Elem().Elem().Interface().(uintptr)
2523 if k != uintptr(i) {
2524 t.Errorf("lost x[%d] = %d, want %d", i, k, i)
2529 func TestAddr(t *testing.T) {
2530 var p struct {
2531 X, Y int
2534 v := ValueOf(&p)
2535 v = v.Elem()
2536 v = v.Addr()
2537 v = v.Elem()
2538 v = v.Field(0)
2539 v.SetInt(2)
2540 if p.X != 2 {
2541 t.Errorf("Addr.Elem.Set failed to set value")
2544 // Again but take address of the ValueOf value.
2545 // Exercises generation of PtrTypes not present in the binary.
2546 q := &p
2547 v = ValueOf(&q).Elem()
2548 v = v.Addr()
2549 v = v.Elem()
2550 v = v.Elem()
2551 v = v.Addr()
2552 v = v.Elem()
2553 v = v.Field(0)
2554 v.SetInt(3)
2555 if p.X != 3 {
2556 t.Errorf("Addr.Elem.Set failed to set value")
2559 // Starting without pointer we should get changed value
2560 // in interface.
2561 qq := p
2562 v = ValueOf(&qq).Elem()
2563 v0 := v
2564 v = v.Addr()
2565 v = v.Elem()
2566 v = v.Field(0)
2567 v.SetInt(4)
2568 if p.X != 3 { // should be unchanged from last time
2569 t.Errorf("somehow value Set changed original p")
2571 p = v0.Interface().(struct {
2572 X, Y int
2574 if p.X != 4 {
2575 t.Errorf("Addr.Elem.Set valued to set value in top value")
2578 // Verify that taking the address of a type gives us a pointer
2579 // which we can convert back using the usual interface
2580 // notation.
2581 var s struct {
2582 B *bool
2584 ps := ValueOf(&s).Elem().Field(0).Addr().Interface()
2585 *(ps.(**bool)) = new(bool)
2586 if s.B == nil {
2587 t.Errorf("Addr.Interface direct assignment failed")
2591 /* gccgo does do allocations here.
2593 func noAlloc(t *testing.T, n int, f func(int)) {
2594 if testing.Short() {
2595 t.Skip("skipping malloc count in short mode")
2597 if runtime.GOMAXPROCS(0) > 1 {
2598 t.Skip("skipping; GOMAXPROCS>1")
2600 i := -1
2601 allocs := testing.AllocsPerRun(n, func() {
2602 f(i)
2605 if allocs > 0 {
2606 t.Errorf("%d iterations: got %v mallocs, want 0", n, allocs)
2610 func TestAllocations(t *testing.T) {
2611 noAlloc(t, 100, func(j int) {
2612 var i interface{}
2613 var v Value
2615 // We can uncomment this when compiler escape analysis
2616 // is good enough to see that the integer assigned to i
2617 // does not escape and therefore need not be allocated.
2619 // i = 42 + j
2620 // v = ValueOf(i)
2621 // if int(v.Int()) != 42+j {
2622 // panic("wrong int")
2623 // }
2625 i = func(j int) int { return j }
2626 v = ValueOf(i)
2627 if v.Interface().(func(int) int)(j) != j {
2628 panic("wrong result")
2635 func TestSmallNegativeInt(t *testing.T) {
2636 i := int16(-1)
2637 v := ValueOf(i)
2638 if v.Int() != -1 {
2639 t.Errorf("int16(-1).Int() returned %v", v.Int())
2643 func TestIndex(t *testing.T) {
2644 xs := []byte{1, 2, 3, 4, 5, 6, 7, 8}
2645 v := ValueOf(xs).Index(3).Interface().(byte)
2646 if v != xs[3] {
2647 t.Errorf("xs.Index(3) = %v; expected %v", v, xs[3])
2649 xa := [8]byte{10, 20, 30, 40, 50, 60, 70, 80}
2650 v = ValueOf(xa).Index(2).Interface().(byte)
2651 if v != xa[2] {
2652 t.Errorf("xa.Index(2) = %v; expected %v", v, xa[2])
2654 s := "0123456789"
2655 v = ValueOf(s).Index(3).Interface().(byte)
2656 if v != s[3] {
2657 t.Errorf("s.Index(3) = %v; expected %v", v, s[3])
2661 func TestSlice(t *testing.T) {
2662 xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
2663 v := ValueOf(xs).Slice(3, 5).Interface().([]int)
2664 if len(v) != 2 {
2665 t.Errorf("len(xs.Slice(3, 5)) = %d", len(v))
2667 if cap(v) != 5 {
2668 t.Errorf("cap(xs.Slice(3, 5)) = %d", cap(v))
2670 if !DeepEqual(v[0:5], xs[3:]) {
2671 t.Errorf("xs.Slice(3, 5)[0:5] = %v", v[0:5])
2673 xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
2674 v = ValueOf(&xa).Elem().Slice(2, 5).Interface().([]int)
2675 if len(v) != 3 {
2676 t.Errorf("len(xa.Slice(2, 5)) = %d", len(v))
2678 if cap(v) != 6 {
2679 t.Errorf("cap(xa.Slice(2, 5)) = %d", cap(v))
2681 if !DeepEqual(v[0:6], xa[2:]) {
2682 t.Errorf("xs.Slice(2, 5)[0:6] = %v", v[0:6])
2684 s := "0123456789"
2685 vs := ValueOf(s).Slice(3, 5).Interface().(string)
2686 if vs != s[3:5] {
2687 t.Errorf("s.Slice(3, 5) = %q; expected %q", vs, s[3:5])
2690 rv := ValueOf(&xs).Elem()
2691 rv = rv.Slice(3, 4)
2692 ptr2 := rv.Pointer()
2693 rv = rv.Slice(5, 5)
2694 ptr3 := rv.Pointer()
2695 if ptr3 != ptr2 {
2696 t.Errorf("xs.Slice(3,4).Slice3(5,5).Pointer() = %#x, want %#x", ptr3, ptr2)
2700 func TestSlice3(t *testing.T) {
2701 xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
2702 v := ValueOf(xs).Slice3(3, 5, 7).Interface().([]int)
2703 if len(v) != 2 {
2704 t.Errorf("len(xs.Slice3(3, 5, 7)) = %d", len(v))
2706 if cap(v) != 4 {
2707 t.Errorf("cap(xs.Slice3(3, 5, 7)) = %d", cap(v))
2709 if !DeepEqual(v[0:4], xs[3:7:7]) {
2710 t.Errorf("xs.Slice3(3, 5, 7)[0:4] = %v", v[0:4])
2712 rv := ValueOf(&xs).Elem()
2713 shouldPanic(func() { rv.Slice3(1, 2, 1) })
2714 shouldPanic(func() { rv.Slice3(1, 1, 11) })
2715 shouldPanic(func() { rv.Slice3(2, 2, 1) })
2717 xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
2718 v = ValueOf(&xa).Elem().Slice3(2, 5, 6).Interface().([]int)
2719 if len(v) != 3 {
2720 t.Errorf("len(xa.Slice(2, 5, 6)) = %d", len(v))
2722 if cap(v) != 4 {
2723 t.Errorf("cap(xa.Slice(2, 5, 6)) = %d", cap(v))
2725 if !DeepEqual(v[0:4], xa[2:6:6]) {
2726 t.Errorf("xs.Slice(2, 5, 6)[0:4] = %v", v[0:4])
2728 rv = ValueOf(&xa).Elem()
2729 shouldPanic(func() { rv.Slice3(1, 2, 1) })
2730 shouldPanic(func() { rv.Slice3(1, 1, 11) })
2731 shouldPanic(func() { rv.Slice3(2, 2, 1) })
2733 s := "hello world"
2734 rv = ValueOf(&s).Elem()
2735 shouldPanic(func() { rv.Slice3(1, 2, 3) })
2737 rv = ValueOf(&xs).Elem()
2738 rv = rv.Slice3(3, 5, 7)
2739 ptr2 := rv.Pointer()
2740 rv = rv.Slice3(4, 4, 4)
2741 ptr3 := rv.Pointer()
2742 if ptr3 != ptr2 {
2743 t.Errorf("xs.Slice3(3,5,7).Slice3(4,4,4).Pointer() = %#x, want %#x", ptr3, ptr2)
2747 func TestSetLenCap(t *testing.T) {
2748 xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
2749 xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
2751 vs := ValueOf(&xs).Elem()
2752 shouldPanic(func() { vs.SetLen(10) })
2753 shouldPanic(func() { vs.SetCap(10) })
2754 shouldPanic(func() { vs.SetLen(-1) })
2755 shouldPanic(func() { vs.SetCap(-1) })
2756 shouldPanic(func() { vs.SetCap(6) }) // smaller than len
2757 vs.SetLen(5)
2758 if len(xs) != 5 || cap(xs) != 8 {
2759 t.Errorf("after SetLen(5), len, cap = %d, %d, want 5, 8", len(xs), cap(xs))
2761 vs.SetCap(6)
2762 if len(xs) != 5 || cap(xs) != 6 {
2763 t.Errorf("after SetCap(6), len, cap = %d, %d, want 5, 6", len(xs), cap(xs))
2765 vs.SetCap(5)
2766 if len(xs) != 5 || cap(xs) != 5 {
2767 t.Errorf("after SetCap(5), len, cap = %d, %d, want 5, 5", len(xs), cap(xs))
2769 shouldPanic(func() { vs.SetCap(4) }) // smaller than len
2770 shouldPanic(func() { vs.SetLen(6) }) // bigger than cap
2772 va := ValueOf(&xa).Elem()
2773 shouldPanic(func() { va.SetLen(8) })
2774 shouldPanic(func() { va.SetCap(8) })
2777 func TestVariadic(t *testing.T) {
2778 var b bytes.Buffer
2779 V := ValueOf
2781 b.Reset()
2782 V(fmt.Fprintf).Call([]Value{V(&b), V("%s, %d world"), V("hello"), V(42)})
2783 if b.String() != "hello, 42 world" {
2784 t.Errorf("after Fprintf Call: %q != %q", b.String(), "hello 42 world")
2787 b.Reset()
2788 V(fmt.Fprintf).CallSlice([]Value{V(&b), V("%s, %d world"), V([]interface{}{"hello", 42})})
2789 if b.String() != "hello, 42 world" {
2790 t.Errorf("after Fprintf CallSlice: %q != %q", b.String(), "hello 42 world")
2794 func TestFuncArg(t *testing.T) {
2795 f1 := func(i int, f func(int) int) int { return f(i) }
2796 f2 := func(i int) int { return i + 1 }
2797 r := ValueOf(f1).Call([]Value{ValueOf(100), ValueOf(f2)})
2798 if r[0].Int() != 101 {
2799 t.Errorf("function returned %d, want 101", r[0].Int())
2803 func TestStructArg(t *testing.T) {
2804 type padded struct {
2805 B string
2806 C int32
2808 var (
2809 gotA padded
2810 gotB uint32
2811 wantA = padded{"3", 4}
2812 wantB = uint32(5)
2814 f := func(a padded, b uint32) {
2815 gotA, gotB = a, b
2817 ValueOf(f).Call([]Value{ValueOf(wantA), ValueOf(wantB)})
2818 if gotA != wantA || gotB != wantB {
2819 t.Errorf("function called with (%v, %v), want (%v, %v)", gotA, gotB, wantA, wantB)
2823 var tagGetTests = []struct {
2824 Tag StructTag
2825 Key string
2826 Value string
2828 {`protobuf:"PB(1,2)"`, `protobuf`, `PB(1,2)`},
2829 {`protobuf:"PB(1,2)"`, `foo`, ``},
2830 {`protobuf:"PB(1,2)"`, `rotobuf`, ``},
2831 {`protobuf:"PB(1,2)" json:"name"`, `json`, `name`},
2832 {`protobuf:"PB(1,2)" json:"name"`, `protobuf`, `PB(1,2)`},
2833 {`k0:"values contain spaces" k1:"and\ttabs"`, "k0", "values contain spaces"},
2834 {`k0:"values contain spaces" k1:"and\ttabs"`, "k1", "and\ttabs"},
2837 func TestTagGet(t *testing.T) {
2838 for _, tt := range tagGetTests {
2839 if v := tt.Tag.Get(tt.Key); v != tt.Value {
2840 t.Errorf("StructTag(%#q).Get(%#q) = %#q, want %#q", tt.Tag, tt.Key, v, tt.Value)
2845 func TestBytes(t *testing.T) {
2846 type B []byte
2847 x := B{1, 2, 3, 4}
2848 y := ValueOf(x).Bytes()
2849 if !bytes.Equal(x, y) {
2850 t.Fatalf("ValueOf(%v).Bytes() = %v", x, y)
2852 if &x[0] != &y[0] {
2853 t.Errorf("ValueOf(%p).Bytes() = %p", &x[0], &y[0])
2857 func TestSetBytes(t *testing.T) {
2858 type B []byte
2859 var x B
2860 y := []byte{1, 2, 3, 4}
2861 ValueOf(&x).Elem().SetBytes(y)
2862 if !bytes.Equal(x, y) {
2863 t.Fatalf("ValueOf(%v).Bytes() = %v", x, y)
2865 if &x[0] != &y[0] {
2866 t.Errorf("ValueOf(%p).Bytes() = %p", &x[0], &y[0])
2870 type Private struct {
2871 x int
2872 y **int
2873 Z int
2876 func (p *Private) m() {
2879 type private struct {
2880 Z int
2881 z int
2882 S string
2883 A [1]Private
2884 T []Private
2887 func (p *private) P() {
2890 type Public struct {
2891 X int
2892 Y **int
2893 private
2896 func (p *Public) M() {
2899 func TestUnexported(t *testing.T) {
2900 var pub Public
2901 pub.S = "S"
2902 pub.T = pub.A[:]
2903 v := ValueOf(&pub)
2904 isValid(v.Elem().Field(0))
2905 isValid(v.Elem().Field(1))
2906 isValid(v.Elem().Field(2))
2907 isValid(v.Elem().FieldByName("X"))
2908 isValid(v.Elem().FieldByName("Y"))
2909 isValid(v.Elem().FieldByName("Z"))
2910 isValid(v.Type().Method(0).Func)
2911 m, _ := v.Type().MethodByName("M")
2912 isValid(m.Func)
2913 m, _ = v.Type().MethodByName("P")
2914 isValid(m.Func)
2915 isNonNil(v.Elem().Field(0).Interface())
2916 isNonNil(v.Elem().Field(1).Interface())
2917 isNonNil(v.Elem().Field(2).Field(2).Index(0))
2918 isNonNil(v.Elem().FieldByName("X").Interface())
2919 isNonNil(v.Elem().FieldByName("Y").Interface())
2920 isNonNil(v.Elem().FieldByName("Z").Interface())
2921 isNonNil(v.Elem().FieldByName("S").Index(0).Interface())
2922 isNonNil(v.Type().Method(0).Func.Interface())
2923 m, _ = v.Type().MethodByName("P")
2924 isNonNil(m.Func.Interface())
2926 var priv Private
2927 v = ValueOf(&priv)
2928 isValid(v.Elem().Field(0))
2929 isValid(v.Elem().Field(1))
2930 isValid(v.Elem().FieldByName("x"))
2931 isValid(v.Elem().FieldByName("y"))
2932 shouldPanic(func() { v.Elem().Field(0).Interface() })
2933 shouldPanic(func() { v.Elem().Field(1).Interface() })
2934 shouldPanic(func() { v.Elem().FieldByName("x").Interface() })
2935 shouldPanic(func() { v.Elem().FieldByName("y").Interface() })
2936 shouldPanic(func() { v.Type().Method(0) })
2939 func TestSetPanic(t *testing.T) {
2940 ok := func(f func()) { f() }
2941 bad := shouldPanic
2942 clear := func(v Value) { v.Set(Zero(v.Type())) }
2944 type t0 struct {
2945 W int
2948 type t1 struct {
2949 Y int
2953 type T2 struct {
2954 Z int
2955 namedT0 t0
2958 type T struct {
2959 X int
2962 NamedT1 t1
2963 NamedT2 T2
2964 namedT1 t1
2965 namedT2 T2
2968 // not addressable
2969 v := ValueOf(T{})
2970 bad(func() { clear(v.Field(0)) }) // .X
2971 bad(func() { clear(v.Field(1)) }) // .t1
2972 bad(func() { clear(v.Field(1).Field(0)) }) // .t1.Y
2973 bad(func() { clear(v.Field(1).Field(1)) }) // .t1.t0
2974 bad(func() { clear(v.Field(1).Field(1).Field(0)) }) // .t1.t0.W
2975 bad(func() { clear(v.Field(2)) }) // .T2
2976 bad(func() { clear(v.Field(2).Field(0)) }) // .T2.Z
2977 bad(func() { clear(v.Field(2).Field(1)) }) // .T2.namedT0
2978 bad(func() { clear(v.Field(2).Field(1).Field(0)) }) // .T2.namedT0.W
2979 bad(func() { clear(v.Field(3)) }) // .NamedT1
2980 bad(func() { clear(v.Field(3).Field(0)) }) // .NamedT1.Y
2981 bad(func() { clear(v.Field(3).Field(1)) }) // .NamedT1.t0
2982 bad(func() { clear(v.Field(3).Field(1).Field(0)) }) // .NamedT1.t0.W
2983 bad(func() { clear(v.Field(4)) }) // .NamedT2
2984 bad(func() { clear(v.Field(4).Field(0)) }) // .NamedT2.Z
2985 bad(func() { clear(v.Field(4).Field(1)) }) // .NamedT2.namedT0
2986 bad(func() { clear(v.Field(4).Field(1).Field(0)) }) // .NamedT2.namedT0.W
2987 bad(func() { clear(v.Field(5)) }) // .namedT1
2988 bad(func() { clear(v.Field(5).Field(0)) }) // .namedT1.Y
2989 bad(func() { clear(v.Field(5).Field(1)) }) // .namedT1.t0
2990 bad(func() { clear(v.Field(5).Field(1).Field(0)) }) // .namedT1.t0.W
2991 bad(func() { clear(v.Field(6)) }) // .namedT2
2992 bad(func() { clear(v.Field(6).Field(0)) }) // .namedT2.Z
2993 bad(func() { clear(v.Field(6).Field(1)) }) // .namedT2.namedT0
2994 bad(func() { clear(v.Field(6).Field(1).Field(0)) }) // .namedT2.namedT0.W
2996 // addressable
2997 v = ValueOf(&T{}).Elem()
2998 ok(func() { clear(v.Field(0)) }) // .X
2999 bad(func() { clear(v.Field(1)) }) // .t1
3000 ok(func() { clear(v.Field(1).Field(0)) }) // .t1.Y
3001 bad(func() { clear(v.Field(1).Field(1)) }) // .t1.t0
3002 ok(func() { clear(v.Field(1).Field(1).Field(0)) }) // .t1.t0.W
3003 ok(func() { clear(v.Field(2)) }) // .T2
3004 ok(func() { clear(v.Field(2).Field(0)) }) // .T2.Z
3005 bad(func() { clear(v.Field(2).Field(1)) }) // .T2.namedT0
3006 bad(func() { clear(v.Field(2).Field(1).Field(0)) }) // .T2.namedT0.W
3007 ok(func() { clear(v.Field(3)) }) // .NamedT1
3008 ok(func() { clear(v.Field(3).Field(0)) }) // .NamedT1.Y
3009 bad(func() { clear(v.Field(3).Field(1)) }) // .NamedT1.t0
3010 ok(func() { clear(v.Field(3).Field(1).Field(0)) }) // .NamedT1.t0.W
3011 ok(func() { clear(v.Field(4)) }) // .NamedT2
3012 ok(func() { clear(v.Field(4).Field(0)) }) // .NamedT2.Z
3013 bad(func() { clear(v.Field(4).Field(1)) }) // .NamedT2.namedT0
3014 bad(func() { clear(v.Field(4).Field(1).Field(0)) }) // .NamedT2.namedT0.W
3015 bad(func() { clear(v.Field(5)) }) // .namedT1
3016 bad(func() { clear(v.Field(5).Field(0)) }) // .namedT1.Y
3017 bad(func() { clear(v.Field(5).Field(1)) }) // .namedT1.t0
3018 bad(func() { clear(v.Field(5).Field(1).Field(0)) }) // .namedT1.t0.W
3019 bad(func() { clear(v.Field(6)) }) // .namedT2
3020 bad(func() { clear(v.Field(6).Field(0)) }) // .namedT2.Z
3021 bad(func() { clear(v.Field(6).Field(1)) }) // .namedT2.namedT0
3022 bad(func() { clear(v.Field(6).Field(1).Field(0)) }) // .namedT2.namedT0.W
3025 type timp int
3027 func (t timp) W() {}
3028 func (t timp) Y() {}
3029 func (t timp) w() {}
3030 func (t timp) y() {}
3032 func TestCallPanic(t *testing.T) {
3033 type t0 interface {
3037 type T1 interface {
3041 type T2 struct {
3045 type T struct {
3046 t0 // 0
3047 T1 // 1
3049 NamedT0 t0 // 2
3050 NamedT1 T1 // 3
3051 NamedT2 T2 // 4
3053 namedT0 t0 // 5
3054 namedT1 T1 // 6
3055 namedT2 T2 // 7
3057 ok := func(f func()) { f() }
3058 bad := shouldPanic
3059 call := func(v Value) { v.Call(nil) }
3061 i := timp(0)
3062 v := ValueOf(T{i, i, i, i, T2{i, i}, i, i, T2{i, i}})
3063 ok(func() { call(v.Field(0).Method(0)) }) // .t0.W
3064 ok(func() { call(v.Field(0).Elem().Method(0)) }) // .t0.W
3065 bad(func() { call(v.Field(0).Method(1)) }) // .t0.w
3066 bad(func() { call(v.Field(0).Elem().Method(2)) }) // .t0.w
3067 ok(func() { call(v.Field(1).Method(0)) }) // .T1.Y
3068 ok(func() { call(v.Field(1).Elem().Method(0)) }) // .T1.Y
3069 bad(func() { call(v.Field(1).Method(1)) }) // .T1.y
3070 bad(func() { call(v.Field(1).Elem().Method(2)) }) // .T1.y
3072 ok(func() { call(v.Field(2).Method(0)) }) // .NamedT0.W
3073 ok(func() { call(v.Field(2).Elem().Method(0)) }) // .NamedT0.W
3074 bad(func() { call(v.Field(2).Method(1)) }) // .NamedT0.w
3075 bad(func() { call(v.Field(2).Elem().Method(2)) }) // .NamedT0.w
3077 ok(func() { call(v.Field(3).Method(0)) }) // .NamedT1.Y
3078 ok(func() { call(v.Field(3).Elem().Method(0)) }) // .NamedT1.Y
3079 bad(func() { call(v.Field(3).Method(1)) }) // .NamedT1.y
3080 bad(func() { call(v.Field(3).Elem().Method(3)) }) // .NamedT1.y
3082 ok(func() { call(v.Field(4).Field(0).Method(0)) }) // .NamedT2.T1.Y
3083 ok(func() { call(v.Field(4).Field(0).Elem().Method(0)) }) // .NamedT2.T1.W
3084 ok(func() { call(v.Field(4).Field(1).Method(0)) }) // .NamedT2.t0.W
3085 ok(func() { call(v.Field(4).Field(1).Elem().Method(0)) }) // .NamedT2.t0.W
3087 bad(func() { call(v.Field(5).Method(0)) }) // .namedT0.W
3088 bad(func() { call(v.Field(5).Elem().Method(0)) }) // .namedT0.W
3089 bad(func() { call(v.Field(5).Method(1)) }) // .namedT0.w
3090 bad(func() { call(v.Field(5).Elem().Method(2)) }) // .namedT0.w
3092 bad(func() { call(v.Field(6).Method(0)) }) // .namedT1.Y
3093 bad(func() { call(v.Field(6).Elem().Method(0)) }) // .namedT1.Y
3094 bad(func() { call(v.Field(6).Method(0)) }) // .namedT1.y
3095 bad(func() { call(v.Field(6).Elem().Method(0)) }) // .namedT1.y
3097 bad(func() { call(v.Field(7).Field(0).Method(0)) }) // .namedT2.T1.Y
3098 bad(func() { call(v.Field(7).Field(0).Elem().Method(0)) }) // .namedT2.T1.W
3099 bad(func() { call(v.Field(7).Field(1).Method(0)) }) // .namedT2.t0.W
3100 bad(func() { call(v.Field(7).Field(1).Elem().Method(0)) }) // .namedT2.t0.W
3103 func shouldPanic(f func()) {
3104 defer func() {
3105 if recover() == nil {
3106 panic("did not panic")
3112 func isNonNil(x interface{}) {
3113 if x == nil {
3114 panic("nil interface")
3118 func isValid(v Value) {
3119 if !v.IsValid() {
3120 panic("zero Value")
3124 func TestAlias(t *testing.T) {
3125 x := string("hello")
3126 v := ValueOf(&x).Elem()
3127 oldvalue := v.Interface()
3128 v.SetString("world")
3129 newvalue := v.Interface()
3131 if oldvalue != "hello" || newvalue != "world" {
3132 t.Errorf("aliasing: old=%q new=%q, want hello, world", oldvalue, newvalue)
3136 var V = ValueOf
3138 func EmptyInterfaceV(x interface{}) Value {
3139 return ValueOf(&x).Elem()
3142 func ReaderV(x io.Reader) Value {
3143 return ValueOf(&x).Elem()
3146 func ReadWriterV(x io.ReadWriter) Value {
3147 return ValueOf(&x).Elem()
3150 type Empty struct{}
3151 type MyStruct struct {
3152 x int `some:"tag"`
3154 type MyString string
3155 type MyBytes []byte
3156 type MyRunes []int32
3157 type MyFunc func()
3158 type MyByte byte
3160 var convertTests = []struct {
3161 in Value
3162 out Value
3164 // numbers
3166 Edit .+1,/\*\//-1>cat >/tmp/x.go && go run /tmp/x.go
3168 package main
3170 import "fmt"
3172 var numbers = []string{
3173 "int8", "uint8", "int16", "uint16",
3174 "int32", "uint32", "int64", "uint64",
3175 "int", "uint", "uintptr",
3176 "float32", "float64",
3179 func main() {
3180 // all pairs but in an unusual order,
3181 // to emit all the int8, uint8 cases
3182 // before n grows too big.
3183 n := 1
3184 for i, f := range numbers {
3185 for _, g := range numbers[i:] {
3186 fmt.Printf("\t{V(%s(%d)), V(%s(%d))},\n", f, n, g, n)
3188 if f != g {
3189 fmt.Printf("\t{V(%s(%d)), V(%s(%d))},\n", g, n, f, n)
3196 {V(int8(1)), V(int8(1))},
3197 {V(int8(2)), V(uint8(2))},
3198 {V(uint8(3)), V(int8(3))},
3199 {V(int8(4)), V(int16(4))},
3200 {V(int16(5)), V(int8(5))},
3201 {V(int8(6)), V(uint16(6))},
3202 {V(uint16(7)), V(int8(7))},
3203 {V(int8(8)), V(int32(8))},
3204 {V(int32(9)), V(int8(9))},
3205 {V(int8(10)), V(uint32(10))},
3206 {V(uint32(11)), V(int8(11))},
3207 {V(int8(12)), V(int64(12))},
3208 {V(int64(13)), V(int8(13))},
3209 {V(int8(14)), V(uint64(14))},
3210 {V(uint64(15)), V(int8(15))},
3211 {V(int8(16)), V(int(16))},
3212 {V(int(17)), V(int8(17))},
3213 {V(int8(18)), V(uint(18))},
3214 {V(uint(19)), V(int8(19))},
3215 {V(int8(20)), V(uintptr(20))},
3216 {V(uintptr(21)), V(int8(21))},
3217 {V(int8(22)), V(float32(22))},
3218 {V(float32(23)), V(int8(23))},
3219 {V(int8(24)), V(float64(24))},
3220 {V(float64(25)), V(int8(25))},
3221 {V(uint8(26)), V(uint8(26))},
3222 {V(uint8(27)), V(int16(27))},
3223 {V(int16(28)), V(uint8(28))},
3224 {V(uint8(29)), V(uint16(29))},
3225 {V(uint16(30)), V(uint8(30))},
3226 {V(uint8(31)), V(int32(31))},
3227 {V(int32(32)), V(uint8(32))},
3228 {V(uint8(33)), V(uint32(33))},
3229 {V(uint32(34)), V(uint8(34))},
3230 {V(uint8(35)), V(int64(35))},
3231 {V(int64(36)), V(uint8(36))},
3232 {V(uint8(37)), V(uint64(37))},
3233 {V(uint64(38)), V(uint8(38))},
3234 {V(uint8(39)), V(int(39))},
3235 {V(int(40)), V(uint8(40))},
3236 {V(uint8(41)), V(uint(41))},
3237 {V(uint(42)), V(uint8(42))},
3238 {V(uint8(43)), V(uintptr(43))},
3239 {V(uintptr(44)), V(uint8(44))},
3240 {V(uint8(45)), V(float32(45))},
3241 {V(float32(46)), V(uint8(46))},
3242 {V(uint8(47)), V(float64(47))},
3243 {V(float64(48)), V(uint8(48))},
3244 {V(int16(49)), V(int16(49))},
3245 {V(int16(50)), V(uint16(50))},
3246 {V(uint16(51)), V(int16(51))},
3247 {V(int16(52)), V(int32(52))},
3248 {V(int32(53)), V(int16(53))},
3249 {V(int16(54)), V(uint32(54))},
3250 {V(uint32(55)), V(int16(55))},
3251 {V(int16(56)), V(int64(56))},
3252 {V(int64(57)), V(int16(57))},
3253 {V(int16(58)), V(uint64(58))},
3254 {V(uint64(59)), V(int16(59))},
3255 {V(int16(60)), V(int(60))},
3256 {V(int(61)), V(int16(61))},
3257 {V(int16(62)), V(uint(62))},
3258 {V(uint(63)), V(int16(63))},
3259 {V(int16(64)), V(uintptr(64))},
3260 {V(uintptr(65)), V(int16(65))},
3261 {V(int16(66)), V(float32(66))},
3262 {V(float32(67)), V(int16(67))},
3263 {V(int16(68)), V(float64(68))},
3264 {V(float64(69)), V(int16(69))},
3265 {V(uint16(70)), V(uint16(70))},
3266 {V(uint16(71)), V(int32(71))},
3267 {V(int32(72)), V(uint16(72))},
3268 {V(uint16(73)), V(uint32(73))},
3269 {V(uint32(74)), V(uint16(74))},
3270 {V(uint16(75)), V(int64(75))},
3271 {V(int64(76)), V(uint16(76))},
3272 {V(uint16(77)), V(uint64(77))},
3273 {V(uint64(78)), V(uint16(78))},
3274 {V(uint16(79)), V(int(79))},
3275 {V(int(80)), V(uint16(80))},
3276 {V(uint16(81)), V(uint(81))},
3277 {V(uint(82)), V(uint16(82))},
3278 {V(uint16(83)), V(uintptr(83))},
3279 {V(uintptr(84)), V(uint16(84))},
3280 {V(uint16(85)), V(float32(85))},
3281 {V(float32(86)), V(uint16(86))},
3282 {V(uint16(87)), V(float64(87))},
3283 {V(float64(88)), V(uint16(88))},
3284 {V(int32(89)), V(int32(89))},
3285 {V(int32(90)), V(uint32(90))},
3286 {V(uint32(91)), V(int32(91))},
3287 {V(int32(92)), V(int64(92))},
3288 {V(int64(93)), V(int32(93))},
3289 {V(int32(94)), V(uint64(94))},
3290 {V(uint64(95)), V(int32(95))},
3291 {V(int32(96)), V(int(96))},
3292 {V(int(97)), V(int32(97))},
3293 {V(int32(98)), V(uint(98))},
3294 {V(uint(99)), V(int32(99))},
3295 {V(int32(100)), V(uintptr(100))},
3296 {V(uintptr(101)), V(int32(101))},
3297 {V(int32(102)), V(float32(102))},
3298 {V(float32(103)), V(int32(103))},
3299 {V(int32(104)), V(float64(104))},
3300 {V(float64(105)), V(int32(105))},
3301 {V(uint32(106)), V(uint32(106))},
3302 {V(uint32(107)), V(int64(107))},
3303 {V(int64(108)), V(uint32(108))},
3304 {V(uint32(109)), V(uint64(109))},
3305 {V(uint64(110)), V(uint32(110))},
3306 {V(uint32(111)), V(int(111))},
3307 {V(int(112)), V(uint32(112))},
3308 {V(uint32(113)), V(uint(113))},
3309 {V(uint(114)), V(uint32(114))},
3310 {V(uint32(115)), V(uintptr(115))},
3311 {V(uintptr(116)), V(uint32(116))},
3312 {V(uint32(117)), V(float32(117))},
3313 {V(float32(118)), V(uint32(118))},
3314 {V(uint32(119)), V(float64(119))},
3315 {V(float64(120)), V(uint32(120))},
3316 {V(int64(121)), V(int64(121))},
3317 {V(int64(122)), V(uint64(122))},
3318 {V(uint64(123)), V(int64(123))},
3319 {V(int64(124)), V(int(124))},
3320 {V(int(125)), V(int64(125))},
3321 {V(int64(126)), V(uint(126))},
3322 {V(uint(127)), V(int64(127))},
3323 {V(int64(128)), V(uintptr(128))},
3324 {V(uintptr(129)), V(int64(129))},
3325 {V(int64(130)), V(float32(130))},
3326 {V(float32(131)), V(int64(131))},
3327 {V(int64(132)), V(float64(132))},
3328 {V(float64(133)), V(int64(133))},
3329 {V(uint64(134)), V(uint64(134))},
3330 {V(uint64(135)), V(int(135))},
3331 {V(int(136)), V(uint64(136))},
3332 {V(uint64(137)), V(uint(137))},
3333 {V(uint(138)), V(uint64(138))},
3334 {V(uint64(139)), V(uintptr(139))},
3335 {V(uintptr(140)), V(uint64(140))},
3336 {V(uint64(141)), V(float32(141))},
3337 {V(float32(142)), V(uint64(142))},
3338 {V(uint64(143)), V(float64(143))},
3339 {V(float64(144)), V(uint64(144))},
3340 {V(int(145)), V(int(145))},
3341 {V(int(146)), V(uint(146))},
3342 {V(uint(147)), V(int(147))},
3343 {V(int(148)), V(uintptr(148))},
3344 {V(uintptr(149)), V(int(149))},
3345 {V(int(150)), V(float32(150))},
3346 {V(float32(151)), V(int(151))},
3347 {V(int(152)), V(float64(152))},
3348 {V(float64(153)), V(int(153))},
3349 {V(uint(154)), V(uint(154))},
3350 {V(uint(155)), V(uintptr(155))},
3351 {V(uintptr(156)), V(uint(156))},
3352 {V(uint(157)), V(float32(157))},
3353 {V(float32(158)), V(uint(158))},
3354 {V(uint(159)), V(float64(159))},
3355 {V(float64(160)), V(uint(160))},
3356 {V(uintptr(161)), V(uintptr(161))},
3357 {V(uintptr(162)), V(float32(162))},
3358 {V(float32(163)), V(uintptr(163))},
3359 {V(uintptr(164)), V(float64(164))},
3360 {V(float64(165)), V(uintptr(165))},
3361 {V(float32(166)), V(float32(166))},
3362 {V(float32(167)), V(float64(167))},
3363 {V(float64(168)), V(float32(168))},
3364 {V(float64(169)), V(float64(169))},
3366 // truncation
3367 {V(float64(1.5)), V(int(1))},
3369 // complex
3370 {V(complex64(1i)), V(complex64(1i))},
3371 {V(complex64(2i)), V(complex128(2i))},
3372 {V(complex128(3i)), V(complex64(3i))},
3373 {V(complex128(4i)), V(complex128(4i))},
3375 // string
3376 {V(string("hello")), V(string("hello"))},
3377 {V(string("bytes1")), V([]byte("bytes1"))},
3378 {V([]byte("bytes2")), V(string("bytes2"))},
3379 {V([]byte("bytes3")), V([]byte("bytes3"))},
3380 {V(string("runes♝")), V([]rune("runes♝"))},
3381 {V([]rune("runes♕")), V(string("runes♕"))},
3382 {V([]rune("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
3383 {V(int('a')), V(string("a"))},
3384 {V(int8('a')), V(string("a"))},
3385 {V(int16('a')), V(string("a"))},
3386 {V(int32('a')), V(string("a"))},
3387 {V(int64('a')), V(string("a"))},
3388 {V(uint('a')), V(string("a"))},
3389 {V(uint8('a')), V(string("a"))},
3390 {V(uint16('a')), V(string("a"))},
3391 {V(uint32('a')), V(string("a"))},
3392 {V(uint64('a')), V(string("a"))},
3393 {V(uintptr('a')), V(string("a"))},
3394 {V(int(-1)), V(string("\uFFFD"))},
3395 {V(int8(-2)), V(string("\uFFFD"))},
3396 {V(int16(-3)), V(string("\uFFFD"))},
3397 {V(int32(-4)), V(string("\uFFFD"))},
3398 {V(int64(-5)), V(string("\uFFFD"))},
3399 {V(uint(0x110001)), V(string("\uFFFD"))},
3400 {V(uint32(0x110002)), V(string("\uFFFD"))},
3401 {V(uint64(0x110003)), V(string("\uFFFD"))},
3402 {V(uintptr(0x110004)), V(string("\uFFFD"))},
3404 // named string
3405 {V(MyString("hello")), V(string("hello"))},
3406 {V(string("hello")), V(MyString("hello"))},
3407 {V(string("hello")), V(string("hello"))},
3408 {V(MyString("hello")), V(MyString("hello"))},
3409 {V(MyString("bytes1")), V([]byte("bytes1"))},
3410 {V([]byte("bytes2")), V(MyString("bytes2"))},
3411 {V([]byte("bytes3")), V([]byte("bytes3"))},
3412 {V(MyString("runes♝")), V([]rune("runes♝"))},
3413 {V([]rune("runes♕")), V(MyString("runes♕"))},
3414 {V([]rune("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
3415 {V([]rune("runes🙈🙉🙊")), V(MyRunes("runes🙈🙉🙊"))},
3416 {V(MyRunes("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
3417 {V(int('a')), V(MyString("a"))},
3418 {V(int8('a')), V(MyString("a"))},
3419 {V(int16('a')), V(MyString("a"))},
3420 {V(int32('a')), V(MyString("a"))},
3421 {V(int64('a')), V(MyString("a"))},
3422 {V(uint('a')), V(MyString("a"))},
3423 {V(uint8('a')), V(MyString("a"))},
3424 {V(uint16('a')), V(MyString("a"))},
3425 {V(uint32('a')), V(MyString("a"))},
3426 {V(uint64('a')), V(MyString("a"))},
3427 {V(uintptr('a')), V(MyString("a"))},
3428 {V(int(-1)), V(MyString("\uFFFD"))},
3429 {V(int8(-2)), V(MyString("\uFFFD"))},
3430 {V(int16(-3)), V(MyString("\uFFFD"))},
3431 {V(int32(-4)), V(MyString("\uFFFD"))},
3432 {V(int64(-5)), V(MyString("\uFFFD"))},
3433 {V(uint(0x110001)), V(MyString("\uFFFD"))},
3434 {V(uint32(0x110002)), V(MyString("\uFFFD"))},
3435 {V(uint64(0x110003)), V(MyString("\uFFFD"))},
3436 {V(uintptr(0x110004)), V(MyString("\uFFFD"))},
3438 // named []byte
3439 {V(string("bytes1")), V(MyBytes("bytes1"))},
3440 {V(MyBytes("bytes2")), V(string("bytes2"))},
3441 {V(MyBytes("bytes3")), V(MyBytes("bytes3"))},
3442 {V(MyString("bytes1")), V(MyBytes("bytes1"))},
3443 {V(MyBytes("bytes2")), V(MyString("bytes2"))},
3445 // named []rune
3446 {V(string("runes♝")), V(MyRunes("runes♝"))},
3447 {V(MyRunes("runes♕")), V(string("runes♕"))},
3448 {V(MyRunes("runes🙈🙉🙊")), V(MyRunes("runes🙈🙉🙊"))},
3449 {V(MyString("runes♝")), V(MyRunes("runes♝"))},
3450 {V(MyRunes("runes♕")), V(MyString("runes♕"))},
3452 // named types and equal underlying types
3453 {V(new(int)), V(new(integer))},
3454 {V(new(integer)), V(new(int))},
3455 {V(Empty{}), V(struct{}{})},
3456 {V(new(Empty)), V(new(struct{}))},
3457 {V(struct{}{}), V(Empty{})},
3458 {V(new(struct{})), V(new(Empty))},
3459 {V(Empty{}), V(Empty{})},
3460 {V(MyBytes{}), V([]byte{})},
3461 {V([]byte{}), V(MyBytes{})},
3462 {V((func())(nil)), V(MyFunc(nil))},
3463 {V((MyFunc)(nil)), V((func())(nil))},
3465 // structs with different tags
3466 {V(struct {
3467 x int `some:"foo"`
3468 }{}), V(struct {
3469 x int `some:"bar"`
3470 }{})},
3472 {V(struct {
3473 x int `some:"bar"`
3474 }{}), V(struct {
3475 x int `some:"foo"`
3476 }{})},
3478 {V(MyStruct{}), V(struct {
3479 x int `some:"foo"`
3480 }{})},
3482 {V(struct {
3483 x int `some:"foo"`
3484 }{}), V(MyStruct{})},
3486 {V(MyStruct{}), V(struct {
3487 x int `some:"bar"`
3488 }{})},
3490 {V(struct {
3491 x int `some:"bar"`
3492 }{}), V(MyStruct{})},
3494 // can convert *byte and *MyByte
3495 {V((*byte)(nil)), V((*MyByte)(nil))},
3496 {V((*MyByte)(nil)), V((*byte)(nil))},
3498 // cannot convert mismatched array sizes
3499 {V([2]byte{}), V([2]byte{})},
3500 {V([3]byte{}), V([3]byte{})},
3502 // cannot convert other instances
3503 {V((**byte)(nil)), V((**byte)(nil))},
3504 {V((**MyByte)(nil)), V((**MyByte)(nil))},
3505 {V((chan byte)(nil)), V((chan byte)(nil))},
3506 {V((chan MyByte)(nil)), V((chan MyByte)(nil))},
3507 {V(([]byte)(nil)), V(([]byte)(nil))},
3508 {V(([]MyByte)(nil)), V(([]MyByte)(nil))},
3509 {V((map[int]byte)(nil)), V((map[int]byte)(nil))},
3510 {V((map[int]MyByte)(nil)), V((map[int]MyByte)(nil))},
3511 {V((map[byte]int)(nil)), V((map[byte]int)(nil))},
3512 {V((map[MyByte]int)(nil)), V((map[MyByte]int)(nil))},
3513 {V([2]byte{}), V([2]byte{})},
3514 {V([2]MyByte{}), V([2]MyByte{})},
3516 // other
3517 {V((***int)(nil)), V((***int)(nil))},
3518 {V((***byte)(nil)), V((***byte)(nil))},
3519 {V((***int32)(nil)), V((***int32)(nil))},
3520 {V((***int64)(nil)), V((***int64)(nil))},
3521 {V((chan int)(nil)), V((<-chan int)(nil))},
3522 {V((chan int)(nil)), V((chan<- int)(nil))},
3523 {V((chan string)(nil)), V((<-chan string)(nil))},
3524 {V((chan string)(nil)), V((chan<- string)(nil))},
3525 {V((chan byte)(nil)), V((chan byte)(nil))},
3526 {V((chan MyByte)(nil)), V((chan MyByte)(nil))},
3527 {V((map[int]bool)(nil)), V((map[int]bool)(nil))},
3528 {V((map[int]byte)(nil)), V((map[int]byte)(nil))},
3529 {V((map[uint]bool)(nil)), V((map[uint]bool)(nil))},
3530 {V([]uint(nil)), V([]uint(nil))},
3531 {V([]int(nil)), V([]int(nil))},
3532 {V(new(interface{})), V(new(interface{}))},
3533 {V(new(io.Reader)), V(new(io.Reader))},
3534 {V(new(io.Writer)), V(new(io.Writer))},
3536 // interfaces
3537 {V(int(1)), EmptyInterfaceV(int(1))},
3538 {V(string("hello")), EmptyInterfaceV(string("hello"))},
3539 {V(new(bytes.Buffer)), ReaderV(new(bytes.Buffer))},
3540 {ReadWriterV(new(bytes.Buffer)), ReaderV(new(bytes.Buffer))},
3541 {V(new(bytes.Buffer)), ReadWriterV(new(bytes.Buffer))},
3544 func TestConvert(t *testing.T) {
3545 canConvert := map[[2]Type]bool{}
3546 all := map[Type]bool{}
3548 for _, tt := range convertTests {
3549 t1 := tt.in.Type()
3550 if !t1.ConvertibleTo(t1) {
3551 t.Errorf("(%s).ConvertibleTo(%s) = false, want true", t1, t1)
3552 continue
3555 t2 := tt.out.Type()
3556 if !t1.ConvertibleTo(t2) {
3557 t.Errorf("(%s).ConvertibleTo(%s) = false, want true", t1, t2)
3558 continue
3561 all[t1] = true
3562 all[t2] = true
3563 canConvert[[2]Type{t1, t2}] = true
3565 // vout1 represents the in value converted to the in type.
3566 v1 := tt.in
3567 vout1 := v1.Convert(t1)
3568 out1 := vout1.Interface()
3569 if vout1.Type() != tt.in.Type() || !DeepEqual(out1, tt.in.Interface()) {
3570 t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t1, out1, tt.in.Interface())
3573 // vout2 represents the in value converted to the out type.
3574 vout2 := v1.Convert(t2)
3575 out2 := vout2.Interface()
3576 if vout2.Type() != tt.out.Type() || !DeepEqual(out2, tt.out.Interface()) {
3577 t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t2, out2, tt.out.Interface())
3580 // vout3 represents a new value of the out type, set to vout2. This makes
3581 // sure the converted value vout2 is really usable as a regular value.
3582 vout3 := New(t2).Elem()
3583 vout3.Set(vout2)
3584 out3 := vout3.Interface()
3585 if vout3.Type() != tt.out.Type() || !DeepEqual(out3, tt.out.Interface()) {
3586 t.Errorf("Set(ValueOf(%T(%[1]v)).Convert(%s)) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t2, out3, tt.out.Interface())
3589 if IsRO(v1) {
3590 t.Errorf("table entry %v is RO, should not be", v1)
3592 if IsRO(vout1) {
3593 t.Errorf("self-conversion output %v is RO, should not be", vout1)
3595 if IsRO(vout2) {
3596 t.Errorf("conversion output %v is RO, should not be", vout2)
3598 if IsRO(vout3) {
3599 t.Errorf("set(conversion output) %v is RO, should not be", vout3)
3601 if !IsRO(MakeRO(v1).Convert(t1)) {
3602 t.Errorf("RO self-conversion output %v is not RO, should be", v1)
3604 if !IsRO(MakeRO(v1).Convert(t2)) {
3605 t.Errorf("RO conversion output %v is not RO, should be", v1)
3609 // Assume that of all the types we saw during the tests,
3610 // if there wasn't an explicit entry for a conversion between
3611 // a pair of types, then it's not to be allowed. This checks for
3612 // things like 'int64' converting to '*int'.
3613 for t1 := range all {
3614 for t2 := range all {
3615 expectOK := t1 == t2 || canConvert[[2]Type{t1, t2}] || t2.Kind() == Interface && t2.NumMethod() == 0
3616 if ok := t1.ConvertibleTo(t2); ok != expectOK {
3617 t.Errorf("(%s).ConvertibleTo(%s) = %v, want %v", t1, t2, ok, expectOK)
3623 type ComparableStruct struct {
3624 X int
3627 type NonComparableStruct struct {
3628 X int
3629 Y map[string]int
3632 var comparableTests = []struct {
3633 typ Type
3634 ok bool
3636 {TypeOf(1), true},
3637 {TypeOf("hello"), true},
3638 {TypeOf(new(byte)), true},
3639 {TypeOf((func())(nil)), false},
3640 {TypeOf([]byte{}), false},
3641 {TypeOf(map[string]int{}), false},
3642 {TypeOf(make(chan int)), true},
3643 {TypeOf(1.5), true},
3644 {TypeOf(false), true},
3645 {TypeOf(1i), true},
3646 {TypeOf(ComparableStruct{}), true},
3647 {TypeOf(NonComparableStruct{}), false},
3648 {TypeOf([10]map[string]int{}), false},
3649 {TypeOf([10]string{}), true},
3650 {TypeOf(new(interface{})).Elem(), true},
3653 func TestComparable(t *testing.T) {
3654 for _, tt := range comparableTests {
3655 if ok := tt.typ.Comparable(); ok != tt.ok {
3656 t.Errorf("TypeOf(%v).Comparable() = %v, want %v", tt.typ, ok, tt.ok)
3661 func TestOverflow(t *testing.T) {
3662 if ovf := V(float64(0)).OverflowFloat(1e300); ovf {
3663 t.Errorf("%v wrongly overflows float64", 1e300)
3666 maxFloat32 := float64((1<<24 - 1) << (127 - 23))
3667 if ovf := V(float32(0)).OverflowFloat(maxFloat32); ovf {
3668 t.Errorf("%v wrongly overflows float32", maxFloat32)
3670 ovfFloat32 := float64((1<<24-1)<<(127-23) + 1<<(127-52))
3671 if ovf := V(float32(0)).OverflowFloat(ovfFloat32); !ovf {
3672 t.Errorf("%v should overflow float32", ovfFloat32)
3674 if ovf := V(float32(0)).OverflowFloat(-ovfFloat32); !ovf {
3675 t.Errorf("%v should overflow float32", -ovfFloat32)
3678 maxInt32 := int64(0x7fffffff)
3679 if ovf := V(int32(0)).OverflowInt(maxInt32); ovf {
3680 t.Errorf("%v wrongly overflows int32", maxInt32)
3682 if ovf := V(int32(0)).OverflowInt(-1 << 31); ovf {
3683 t.Errorf("%v wrongly overflows int32", -int64(1)<<31)
3685 ovfInt32 := int64(1 << 31)
3686 if ovf := V(int32(0)).OverflowInt(ovfInt32); !ovf {
3687 t.Errorf("%v should overflow int32", ovfInt32)
3690 maxUint32 := uint64(0xffffffff)
3691 if ovf := V(uint32(0)).OverflowUint(maxUint32); ovf {
3692 t.Errorf("%v wrongly overflows uint32", maxUint32)
3694 ovfUint32 := uint64(1 << 32)
3695 if ovf := V(uint32(0)).OverflowUint(ovfUint32); !ovf {
3696 t.Errorf("%v should overflow uint32", ovfUint32)
3700 func checkSameType(t *testing.T, x, y interface{}) {
3701 if TypeOf(x) != TypeOf(y) {
3702 t.Errorf("did not find preexisting type for %s (vs %s)", TypeOf(x), TypeOf(y))
3706 func TestArrayOf(t *testing.T) {
3707 // check construction and use of type not in binary
3708 for _, table := range []struct {
3709 n int
3710 value func(i int) interface{}
3711 comparable bool
3712 want string
3715 n: 0,
3716 value: func(i int) interface{} { type Tint int; return Tint(i) },
3717 comparable: true,
3718 want: "[]",
3721 n: 10,
3722 value: func(i int) interface{} { type Tint int; return Tint(i) },
3723 comparable: true,
3724 want: "[0 1 2 3 4 5 6 7 8 9]",
3727 n: 10,
3728 value: func(i int) interface{} { type Tfloat float64; return Tfloat(i) },
3729 comparable: true,
3730 want: "[0 1 2 3 4 5 6 7 8 9]",
3733 n: 10,
3734 value: func(i int) interface{} { type Tstring string; return Tstring(strconv.Itoa(i)) },
3735 comparable: true,
3736 want: "[0 1 2 3 4 5 6 7 8 9]",
3739 n: 10,
3740 value: func(i int) interface{} { type Tstruct struct{ V int }; return Tstruct{i} },
3741 comparable: true,
3742 want: "[{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}]",
3745 n: 10,
3746 value: func(i int) interface{} { type Tint int; return []Tint{Tint(i)} },
3747 comparable: false,
3748 want: "[[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]]",
3751 n: 10,
3752 value: func(i int) interface{} { type Tint int; return [1]Tint{Tint(i)} },
3753 comparable: true,
3754 want: "[[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]]",
3757 n: 10,
3758 value: func(i int) interface{} { type Tstruct struct{ V [1]int }; return Tstruct{[1]int{i}} },
3759 comparable: true,
3760 want: "[{[0]} {[1]} {[2]} {[3]} {[4]} {[5]} {[6]} {[7]} {[8]} {[9]}]",
3763 n: 10,
3764 value: func(i int) interface{} { type Tstruct struct{ V []int }; return Tstruct{[]int{i}} },
3765 comparable: false,
3766 want: "[{[0]} {[1]} {[2]} {[3]} {[4]} {[5]} {[6]} {[7]} {[8]} {[9]}]",
3769 n: 10,
3770 value: func(i int) interface{} { type TstructUV struct{ U, V int }; return TstructUV{i, i} },
3771 comparable: true,
3772 want: "[{0 0} {1 1} {2 2} {3 3} {4 4} {5 5} {6 6} {7 7} {8 8} {9 9}]",
3775 n: 10,
3776 value: func(i int) interface{} {
3777 type TstructUV struct {
3778 U int
3779 V float64
3781 return TstructUV{i, float64(i)}
3783 comparable: true,
3784 want: "[{0 0} {1 1} {2 2} {3 3} {4 4} {5 5} {6 6} {7 7} {8 8} {9 9}]",
3787 at := ArrayOf(table.n, TypeOf(table.value(0)))
3788 v := New(at).Elem()
3789 vok := New(at).Elem()
3790 vnot := New(at).Elem()
3791 for i := 0; i < v.Len(); i++ {
3792 v.Index(i).Set(ValueOf(table.value(i)))
3793 vok.Index(i).Set(ValueOf(table.value(i)))
3794 j := i
3795 if i+1 == v.Len() {
3796 j = i + 1
3798 vnot.Index(i).Set(ValueOf(table.value(j))) // make it differ only by last element
3800 s := fmt.Sprint(v.Interface())
3801 if s != table.want {
3802 t.Errorf("constructed array = %s, want %s", s, table.want)
3805 if table.comparable != at.Comparable() {
3806 t.Errorf("constructed array (%#v) is comparable=%v, want=%v", v.Interface(), at.Comparable(), table.comparable)
3808 if table.comparable {
3809 if table.n > 0 {
3810 if DeepEqual(vnot.Interface(), v.Interface()) {
3811 t.Errorf(
3812 "arrays (%#v) compare ok (but should not)",
3813 v.Interface(),
3817 if !DeepEqual(vok.Interface(), v.Interface()) {
3818 t.Errorf(
3819 "arrays (%#v) compare NOT-ok (but should)",
3820 v.Interface(),
3826 // check that type already in binary is found
3827 type T int
3828 checkSameType(t, Zero(ArrayOf(5, TypeOf(T(1)))).Interface(), [5]T{})
3831 func TestArrayOfGC(t *testing.T) {
3832 type T *uintptr
3833 tt := TypeOf(T(nil))
3834 const n = 100
3835 var x []interface{}
3836 for i := 0; i < n; i++ {
3837 v := New(ArrayOf(n, tt)).Elem()
3838 for j := 0; j < v.Len(); j++ {
3839 p := new(uintptr)
3840 *p = uintptr(i*n + j)
3841 v.Index(j).Set(ValueOf(p).Convert(tt))
3843 x = append(x, v.Interface())
3845 runtime.GC()
3847 for i, xi := range x {
3848 v := ValueOf(xi)
3849 for j := 0; j < v.Len(); j++ {
3850 k := v.Index(j).Elem().Interface()
3851 if k != uintptr(i*n+j) {
3852 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
3858 func TestArrayOfAlg(t *testing.T) {
3859 at := ArrayOf(6, TypeOf(byte(0)))
3860 v1 := New(at).Elem()
3861 v2 := New(at).Elem()
3862 if v1.Interface() != v1.Interface() {
3863 t.Errorf("constructed array %v not equal to itself", v1.Interface())
3865 v1.Index(5).Set(ValueOf(byte(1)))
3866 if i1, i2 := v1.Interface(), v2.Interface(); i1 == i2 {
3867 t.Errorf("constructed arrays %v and %v should not be equal", i1, i2)
3870 at = ArrayOf(6, TypeOf([]int(nil)))
3871 v1 = New(at).Elem()
3872 shouldPanic(func() { _ = v1.Interface() == v1.Interface() })
3875 func TestArrayOfGenericAlg(t *testing.T) {
3876 at1 := ArrayOf(5, TypeOf(string("")))
3877 at := ArrayOf(6, at1)
3878 v1 := New(at).Elem()
3879 v2 := New(at).Elem()
3880 if v1.Interface() != v1.Interface() {
3881 t.Errorf("constructed array %v not equal to itself", v1.Interface())
3884 v1.Index(0).Index(0).Set(ValueOf("abc"))
3885 v2.Index(0).Index(0).Set(ValueOf("efg"))
3886 if i1, i2 := v1.Interface(), v2.Interface(); i1 == i2 {
3887 t.Errorf("constructed arrays %v and %v should not be equal", i1, i2)
3890 v1.Index(0).Index(0).Set(ValueOf("abc"))
3891 v2.Index(0).Index(0).Set(ValueOf((v1.Index(0).Index(0).String() + " ")[:3]))
3892 if i1, i2 := v1.Interface(), v2.Interface(); i1 != i2 {
3893 t.Errorf("constructed arrays %v and %v should be equal", i1, i2)
3896 // Test hash
3897 m := MakeMap(MapOf(at, TypeOf(int(0))))
3898 m.SetMapIndex(v1, ValueOf(1))
3899 if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
3900 t.Errorf("constructed arrays %v and %v have different hashes", i1, i2)
3904 func TestArrayOfDirectIface(t *testing.T) {
3905 t.Skip("skipping test because gccgo uses a different directiface value")
3907 type T [1]*byte
3908 i1 := Zero(TypeOf(T{})).Interface()
3909 v1 := ValueOf(&i1).Elem()
3910 p1 := v1.InterfaceData()[1]
3912 i2 := Zero(ArrayOf(1, PtrTo(TypeOf(int8(0))))).Interface()
3913 v2 := ValueOf(&i2).Elem()
3914 p2 := v2.InterfaceData()[1]
3916 if p1 != 0 {
3917 t.Errorf("got p1=%v. want=%v", p1, nil)
3920 if p2 != 0 {
3921 t.Errorf("got p2=%v. want=%v", p2, nil)
3925 type T [0]*byte
3926 i1 := Zero(TypeOf(T{})).Interface()
3927 v1 := ValueOf(&i1).Elem()
3928 p1 := v1.InterfaceData()[1]
3930 i2 := Zero(ArrayOf(0, PtrTo(TypeOf(int8(0))))).Interface()
3931 v2 := ValueOf(&i2).Elem()
3932 p2 := v2.InterfaceData()[1]
3934 if p1 == 0 {
3935 t.Errorf("got p1=%v. want=not-%v", p1, nil)
3938 if p2 == 0 {
3939 t.Errorf("got p2=%v. want=not-%v", p2, nil)
3944 func TestSliceOf(t *testing.T) {
3945 // check construction and use of type not in binary
3946 type T int
3947 st := SliceOf(TypeOf(T(1)))
3948 if got, want := st.String(), "[]reflect_test.T"; got != want {
3949 t.Errorf("SliceOf(T(1)).String()=%q, want %q", got, want)
3951 v := MakeSlice(st, 10, 10)
3952 runtime.GC()
3953 for i := 0; i < v.Len(); i++ {
3954 v.Index(i).Set(ValueOf(T(i)))
3955 runtime.GC()
3957 s := fmt.Sprint(v.Interface())
3958 want := "[0 1 2 3 4 5 6 7 8 9]"
3959 if s != want {
3960 t.Errorf("constructed slice = %s, want %s", s, want)
3963 // check that type already in binary is found
3964 type T1 int
3965 checkSameType(t, Zero(SliceOf(TypeOf(T1(1)))).Interface(), []T1{})
3968 func TestSliceOverflow(t *testing.T) {
3969 // check that MakeSlice panics when size of slice overflows uint
3970 const S = 1e6
3971 s := uint(S)
3972 l := (1<<(unsafe.Sizeof((*byte)(nil))*8)-1)/s + 1
3973 if l*s >= s {
3974 t.Fatal("slice size does not overflow")
3976 var x [S]byte
3977 st := SliceOf(TypeOf(x))
3978 defer func() {
3979 err := recover()
3980 if err == nil {
3981 t.Fatal("slice overflow does not panic")
3984 MakeSlice(st, int(l), int(l))
3987 func TestSliceOfGC(t *testing.T) {
3988 type T *uintptr
3989 tt := TypeOf(T(nil))
3990 st := SliceOf(tt)
3991 const n = 100
3992 var x []interface{}
3993 for i := 0; i < n; i++ {
3994 v := MakeSlice(st, n, n)
3995 for j := 0; j < v.Len(); j++ {
3996 p := new(uintptr)
3997 *p = uintptr(i*n + j)
3998 v.Index(j).Set(ValueOf(p).Convert(tt))
4000 x = append(x, v.Interface())
4002 runtime.GC()
4004 for i, xi := range x {
4005 v := ValueOf(xi)
4006 for j := 0; j < v.Len(); j++ {
4007 k := v.Index(j).Elem().Interface()
4008 if k != uintptr(i*n+j) {
4009 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
4015 func TestStructOf(t *testing.T) {
4016 // check construction and use of type not in binary
4017 fields := []StructField{
4018 StructField{
4019 Name: "S",
4020 Tag: "s",
4021 Type: TypeOf(""),
4023 StructField{
4024 Name: "X",
4025 Tag: "x",
4026 Type: TypeOf(byte(0)),
4028 StructField{
4029 Name: "Y",
4030 Type: TypeOf(uint64(0)),
4032 StructField{
4033 Name: "Z",
4034 Type: TypeOf([3]uint16{}),
4038 st := StructOf(fields)
4039 v := New(st).Elem()
4040 runtime.GC()
4041 v.FieldByName("X").Set(ValueOf(byte(2)))
4042 v.FieldByIndex([]int{1}).Set(ValueOf(byte(1)))
4043 runtime.GC()
4045 s := fmt.Sprint(v.Interface())
4046 want := `{ 1 0 [0 0 0]}`
4047 if s != want {
4048 t.Errorf("constructed struct = %s, want %s", s, want)
4050 const stStr = `struct { S string "s"; X uint8 "x"; Y uint64; Z [3]uint16 }`
4051 if got, want := st.String(), stStr; got != want {
4052 t.Errorf("StructOf(fields).String()=%q, want %q", got, want)
4055 // check the size, alignment and field offsets
4056 stt := TypeOf(struct {
4057 String string
4058 X byte
4059 Y uint64
4060 Z [3]uint16
4061 }{})
4062 if st.Size() != stt.Size() {
4063 t.Errorf("constructed struct size = %v, want %v", st.Size(), stt.Size())
4065 if st.Align() != stt.Align() {
4066 t.Errorf("constructed struct align = %v, want %v", st.Align(), stt.Align())
4068 if st.FieldAlign() != stt.FieldAlign() {
4069 t.Errorf("constructed struct field align = %v, want %v", st.FieldAlign(), stt.FieldAlign())
4071 for i := 0; i < st.NumField(); i++ {
4072 o1 := st.Field(i).Offset
4073 o2 := stt.Field(i).Offset
4074 if o1 != o2 {
4075 t.Errorf("constructed struct field %v offset = %v, want %v", i, o1, o2)
4079 // Check size and alignment with a trailing zero-sized field.
4080 st = StructOf([]StructField{
4082 Name: "F1",
4083 Type: TypeOf(byte(0)),
4086 Name: "F2",
4087 Type: TypeOf([0]*byte{}),
4090 stt = TypeOf(struct {
4091 G1 byte
4092 G2 [0]*byte
4093 }{})
4094 // Broken with gccgo for now--gccgo does not pad structs yet.
4095 // if st.Size() != stt.Size() {
4096 // t.Errorf("constructed zero-padded struct size = %v, want %v", st.Size(), stt.Size())
4097 // }
4098 if st.Align() != stt.Align() {
4099 t.Errorf("constructed zero-padded struct align = %v, want %v", st.Align(), stt.Align())
4101 if st.FieldAlign() != stt.FieldAlign() {
4102 t.Errorf("constructed zero-padded struct field align = %v, want %v", st.FieldAlign(), stt.FieldAlign())
4104 for i := 0; i < st.NumField(); i++ {
4105 o1 := st.Field(i).Offset
4106 o2 := stt.Field(i).Offset
4107 if o1 != o2 {
4108 t.Errorf("constructed zero-padded struct field %v offset = %v, want %v", i, o1, o2)
4112 // check duplicate names
4113 shouldPanic(func() {
4114 StructOf([]StructField{
4115 StructField{Name: "string", Type: TypeOf("")},
4116 StructField{Name: "string", Type: TypeOf("")},
4119 shouldPanic(func() {
4120 StructOf([]StructField{
4121 StructField{Type: TypeOf("")},
4122 StructField{Name: "string", Type: TypeOf("")},
4125 shouldPanic(func() {
4126 StructOf([]StructField{
4127 StructField{Type: TypeOf("")},
4128 StructField{Type: TypeOf("")},
4131 // check that type already in binary is found
4132 checkSameType(t, Zero(StructOf(fields[2:3])).Interface(), struct{ Y uint64 }{})
4135 func TestStructOfExportRules(t *testing.T) {
4136 type S1 struct{}
4137 type s2 struct{}
4138 type ΦType struct{}
4139 type φType struct{}
4141 testPanic := func(i int, mustPanic bool, f func()) {
4142 defer func() {
4143 err := recover()
4144 if err == nil && mustPanic {
4145 t.Errorf("test-%d did not panic", i)
4147 if err != nil && !mustPanic {
4148 t.Errorf("test-%d panicked: %v\n", i, err)
4154 for i, test := range []struct {
4155 field StructField
4156 mustPanic bool
4157 exported bool
4160 field: StructField{Name: "", Type: TypeOf(S1{})},
4161 mustPanic: false,
4162 exported: true,
4165 field: StructField{Name: "", Type: TypeOf((*S1)(nil))},
4166 mustPanic: false,
4167 exported: true,
4170 field: StructField{Name: "", Type: TypeOf(s2{})},
4171 mustPanic: false,
4172 exported: false,
4175 field: StructField{Name: "", Type: TypeOf((*s2)(nil))},
4176 mustPanic: false,
4177 exported: false,
4180 field: StructField{Name: "", Type: TypeOf(S1{}), PkgPath: "other/pkg"},
4181 mustPanic: true,
4182 exported: true,
4185 field: StructField{Name: "", Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"},
4186 mustPanic: true,
4187 exported: true,
4190 field: StructField{Name: "", Type: TypeOf(s2{}), PkgPath: "other/pkg"},
4191 mustPanic: true,
4192 exported: false,
4195 field: StructField{Name: "", Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"},
4196 mustPanic: true,
4197 exported: false,
4200 field: StructField{Name: "S", Type: TypeOf(S1{})},
4201 mustPanic: false,
4202 exported: true,
4205 field: StructField{Name: "S", Type: TypeOf((*S1)(nil))},
4206 mustPanic: false,
4207 exported: true,
4210 field: StructField{Name: "S", Type: TypeOf(s2{})},
4211 mustPanic: false,
4212 exported: true,
4215 field: StructField{Name: "S", Type: TypeOf((*s2)(nil))},
4216 mustPanic: false,
4217 exported: true,
4220 field: StructField{Name: "s", Type: TypeOf(S1{})},
4221 mustPanic: true,
4222 exported: false,
4225 field: StructField{Name: "s", Type: TypeOf((*S1)(nil))},
4226 mustPanic: true,
4227 exported: false,
4230 field: StructField{Name: "s", Type: TypeOf(s2{})},
4231 mustPanic: true,
4232 exported: false,
4235 field: StructField{Name: "s", Type: TypeOf((*s2)(nil))},
4236 mustPanic: true,
4237 exported: false,
4240 field: StructField{Name: "s", Type: TypeOf(S1{}), PkgPath: "other/pkg"},
4241 mustPanic: true, // TODO(sbinet): creating a name with a package path
4242 exported: false,
4245 field: StructField{Name: "s", Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"},
4246 mustPanic: true, // TODO(sbinet): creating a name with a package path
4247 exported: false,
4250 field: StructField{Name: "s", Type: TypeOf(s2{}), PkgPath: "other/pkg"},
4251 mustPanic: true, // TODO(sbinet): creating a name with a package path
4252 exported: false,
4255 field: StructField{Name: "s", Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"},
4256 mustPanic: true, // TODO(sbinet): creating a name with a package path
4257 exported: false,
4260 field: StructField{Name: "", Type: TypeOf(ΦType{})},
4261 mustPanic: false,
4262 exported: true,
4265 field: StructField{Name: "", Type: TypeOf(φType{})},
4266 mustPanic: false,
4267 exported: false,
4270 field: StructField{Name: "Φ", Type: TypeOf(0)},
4271 mustPanic: false,
4272 exported: true,
4275 field: StructField{Name: "φ", Type: TypeOf(0)},
4276 mustPanic: false,
4277 exported: false,
4280 testPanic(i, test.mustPanic, func() {
4281 typ := StructOf([]StructField{test.field})
4282 if typ == nil {
4283 t.Errorf("test-%d: error creating struct type", i)
4284 return
4286 field := typ.Field(0)
4287 n := field.Name
4288 if n == "" {
4289 n = field.Type.Name()
4291 exported := isExported(n)
4292 if exported != test.exported {
4293 t.Errorf("test-%d: got exported=%v want exported=%v", i, exported, test.exported)
4299 // isExported reports whether name is an exported Go symbol
4300 // (that is, whether it begins with an upper-case letter).
4302 func isExported(name string) bool {
4303 ch, _ := utf8.DecodeRuneInString(name)
4304 return unicode.IsUpper(ch)
4307 func TestStructOfGC(t *testing.T) {
4308 type T *uintptr
4309 tt := TypeOf(T(nil))
4310 fields := []StructField{
4311 {Name: "X", Type: tt},
4312 {Name: "Y", Type: tt},
4314 st := StructOf(fields)
4316 const n = 10000
4317 var x []interface{}
4318 for i := 0; i < n; i++ {
4319 v := New(st).Elem()
4320 for j := 0; j < v.NumField(); j++ {
4321 p := new(uintptr)
4322 *p = uintptr(i*n + j)
4323 v.Field(j).Set(ValueOf(p).Convert(tt))
4325 x = append(x, v.Interface())
4327 runtime.GC()
4329 for i, xi := range x {
4330 v := ValueOf(xi)
4331 for j := 0; j < v.NumField(); j++ {
4332 k := v.Field(j).Elem().Interface()
4333 if k != uintptr(i*n+j) {
4334 t.Errorf("lost x[%d].%c = %d, want %d", i, "XY"[j], k, i*n+j)
4340 func TestStructOfAlg(t *testing.T) {
4341 st := StructOf([]StructField{{Name: "X", Tag: "x", Type: TypeOf(int(0))}})
4342 v1 := New(st).Elem()
4343 v2 := New(st).Elem()
4344 if !DeepEqual(v1.Interface(), v1.Interface()) {
4345 t.Errorf("constructed struct %v not equal to itself", v1.Interface())
4347 v1.FieldByName("X").Set(ValueOf(int(1)))
4348 if i1, i2 := v1.Interface(), v2.Interface(); DeepEqual(i1, i2) {
4349 t.Errorf("constructed structs %v and %v should not be equal", i1, i2)
4352 st = StructOf([]StructField{{Name: "X", Tag: "x", Type: TypeOf([]int(nil))}})
4353 v1 = New(st).Elem()
4354 shouldPanic(func() { _ = v1.Interface() == v1.Interface() })
4357 func TestStructOfGenericAlg(t *testing.T) {
4358 st1 := StructOf([]StructField{
4359 {Name: "X", Tag: "x", Type: TypeOf(int64(0))},
4360 {Name: "Y", Type: TypeOf(string(""))},
4362 st := StructOf([]StructField{
4363 {Name: "S0", Type: st1},
4364 {Name: "S1", Type: st1},
4367 for _, table := range []struct {
4368 rt Type
4369 idx []int
4372 rt: st,
4373 idx: []int{0, 1},
4376 rt: st1,
4377 idx: []int{1},
4380 rt: StructOf(
4381 []StructField{
4382 {Name: "XX", Type: TypeOf([0]int{})},
4383 {Name: "YY", Type: TypeOf("")},
4386 idx: []int{1},
4389 rt: StructOf(
4390 []StructField{
4391 {Name: "XX", Type: TypeOf([0]int{})},
4392 {Name: "YY", Type: TypeOf("")},
4393 {Name: "ZZ", Type: TypeOf([2]int{})},
4396 idx: []int{1},
4399 rt: StructOf(
4400 []StructField{
4401 {Name: "XX", Type: TypeOf([1]int{})},
4402 {Name: "YY", Type: TypeOf("")},
4405 idx: []int{1},
4408 rt: StructOf(
4409 []StructField{
4410 {Name: "XX", Type: TypeOf([1]int{})},
4411 {Name: "YY", Type: TypeOf("")},
4412 {Name: "ZZ", Type: TypeOf([1]int{})},
4415 idx: []int{1},
4418 rt: StructOf(
4419 []StructField{
4420 {Name: "XX", Type: TypeOf([2]int{})},
4421 {Name: "YY", Type: TypeOf("")},
4422 {Name: "ZZ", Type: TypeOf([2]int{})},
4425 idx: []int{1},
4428 rt: StructOf(
4429 []StructField{
4430 {Name: "XX", Type: TypeOf(int64(0))},
4431 {Name: "YY", Type: TypeOf(byte(0))},
4432 {Name: "ZZ", Type: TypeOf("")},
4435 idx: []int{2},
4438 rt: StructOf(
4439 []StructField{
4440 {Name: "XX", Type: TypeOf(int64(0))},
4441 {Name: "YY", Type: TypeOf(int64(0))},
4442 {Name: "ZZ", Type: TypeOf("")},
4443 {Name: "AA", Type: TypeOf([1]int64{})},
4446 idx: []int{2},
4449 v1 := New(table.rt).Elem()
4450 v2 := New(table.rt).Elem()
4452 if !DeepEqual(v1.Interface(), v1.Interface()) {
4453 t.Errorf("constructed struct %v not equal to itself", v1.Interface())
4456 v1.FieldByIndex(table.idx).Set(ValueOf("abc"))
4457 v2.FieldByIndex(table.idx).Set(ValueOf("def"))
4458 if i1, i2 := v1.Interface(), v2.Interface(); DeepEqual(i1, i2) {
4459 t.Errorf("constructed structs %v and %v should not be equal", i1, i2)
4462 abc := "abc"
4463 v1.FieldByIndex(table.idx).Set(ValueOf(abc))
4464 val := "+" + abc + "-"
4465 v2.FieldByIndex(table.idx).Set(ValueOf(val[1:4]))
4466 if i1, i2 := v1.Interface(), v2.Interface(); !DeepEqual(i1, i2) {
4467 t.Errorf("constructed structs %v and %v should be equal", i1, i2)
4470 // Test hash
4471 m := MakeMap(MapOf(table.rt, TypeOf(int(0))))
4472 m.SetMapIndex(v1, ValueOf(1))
4473 if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
4474 t.Errorf("constructed structs %#v and %#v have different hashes", i1, i2)
4477 v2.FieldByIndex(table.idx).Set(ValueOf("abc"))
4478 if i1, i2 := v1.Interface(), v2.Interface(); !DeepEqual(i1, i2) {
4479 t.Errorf("constructed structs %v and %v should be equal", i1, i2)
4482 if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
4483 t.Errorf("constructed structs %v and %v have different hashes", i1, i2)
4489 gccgo does not use the same directiface settings as gc.
4491 func TestStructOfDirectIface(t *testing.T) {
4493 type T struct{ X [1]*byte }
4494 i1 := Zero(TypeOf(T{})).Interface()
4495 v1 := ValueOf(&i1).Elem()
4496 p1 := v1.InterfaceData()[1]
4498 i2 := Zero(StructOf([]StructField{
4500 Name: "X",
4501 Type: ArrayOf(1, TypeOf((*int8)(nil))),
4503 })).Interface()
4504 v2 := ValueOf(&i2).Elem()
4505 p2 := v2.InterfaceData()[1]
4507 if p1 != 0 {
4508 t.Errorf("got p1=%v. want=%v", p1, nil)
4511 if p2 != 0 {
4512 t.Errorf("got p2=%v. want=%v", p2, nil)
4516 type T struct{ X [0]*byte }
4517 i1 := Zero(TypeOf(T{})).Interface()
4518 v1 := ValueOf(&i1).Elem()
4519 p1 := v1.InterfaceData()[1]
4521 i2 := Zero(StructOf([]StructField{
4523 Name: "X",
4524 Type: ArrayOf(0, TypeOf((*int8)(nil))),
4526 })).Interface()
4527 v2 := ValueOf(&i2).Elem()
4528 p2 := v2.InterfaceData()[1]
4530 if p1 == 0 {
4531 t.Errorf("got p1=%v. want=not-%v", p1, nil)
4534 if p2 == 0 {
4535 t.Errorf("got p2=%v. want=not-%v", p2, nil)
4541 type StructI int
4543 func (i StructI) Get() int { return int(i) }
4545 type StructIPtr int
4547 func (i *StructIPtr) Get() int { return int(*i) }
4550 gccgo does not yet support StructOf with methods.
4552 func TestStructOfWithInterface(t *testing.T) {
4553 const want = 42
4554 type Iface interface {
4555 Get() int
4557 for i, table := range []struct {
4558 typ Type
4559 val Value
4560 impl bool
4563 typ: TypeOf(StructI(want)),
4564 val: ValueOf(StructI(want)),
4565 impl: true,
4568 typ: PtrTo(TypeOf(StructI(want))),
4569 val: ValueOf(func() interface{} {
4570 v := StructI(want)
4571 return &v
4572 }()),
4573 impl: true,
4576 typ: PtrTo(TypeOf(StructIPtr(want))),
4577 val: ValueOf(func() interface{} {
4578 v := StructIPtr(want)
4579 return &v
4580 }()),
4581 impl: true,
4584 typ: TypeOf(StructIPtr(want)),
4585 val: ValueOf(StructIPtr(want)),
4586 impl: false,
4588 // {
4589 // typ: TypeOf((*Iface)(nil)).Elem(), // FIXME(sbinet): fix method.ifn/tfn
4590 // val: ValueOf(StructI(want)),
4591 // impl: true,
4592 // },
4594 rt := StructOf(
4595 []StructField{
4597 Name: "",
4598 PkgPath: "",
4599 Type: table.typ,
4603 rv := New(rt).Elem()
4604 rv.Field(0).Set(table.val)
4606 if _, ok := rv.Interface().(Iface); ok != table.impl {
4607 if table.impl {
4608 t.Errorf("test-%d: type=%v fails to implement Iface.\n", i, table.typ)
4609 } else {
4610 t.Errorf("test-%d: type=%v should NOT implement Iface\n", i, table.typ)
4612 continue
4615 if !table.impl {
4616 continue
4619 v := rv.Interface().(Iface).Get()
4620 if v != want {
4621 t.Errorf("test-%d: x.Get()=%v. want=%v\n", i, v, want)
4624 fct := rv.MethodByName("Get")
4625 out := fct.Call(nil)
4626 if !DeepEqual(out[0].Interface(), want) {
4627 t.Errorf("test-%d: x.Get()=%v. want=%v\n", i, out[0].Interface(), want)
4633 func TestChanOf(t *testing.T) {
4634 // check construction and use of type not in binary
4635 type T string
4636 ct := ChanOf(BothDir, TypeOf(T("")))
4637 v := MakeChan(ct, 2)
4638 runtime.GC()
4639 v.Send(ValueOf(T("hello")))
4640 runtime.GC()
4641 v.Send(ValueOf(T("world")))
4642 runtime.GC()
4644 sv1, _ := v.Recv()
4645 sv2, _ := v.Recv()
4646 s1 := sv1.String()
4647 s2 := sv2.String()
4648 if s1 != "hello" || s2 != "world" {
4649 t.Errorf("constructed chan: have %q, %q, want %q, %q", s1, s2, "hello", "world")
4652 // check that type already in binary is found
4653 type T1 int
4654 checkSameType(t, Zero(ChanOf(BothDir, TypeOf(T1(1)))).Interface(), (chan T1)(nil))
4657 func TestChanOfDir(t *testing.T) {
4658 // check construction and use of type not in binary
4659 type T string
4660 crt := ChanOf(RecvDir, TypeOf(T("")))
4661 cst := ChanOf(SendDir, TypeOf(T("")))
4663 // check that type already in binary is found
4664 type T1 int
4665 checkSameType(t, Zero(ChanOf(RecvDir, TypeOf(T1(1)))).Interface(), (<-chan T1)(nil))
4666 checkSameType(t, Zero(ChanOf(SendDir, TypeOf(T1(1)))).Interface(), (chan<- T1)(nil))
4668 // check String form of ChanDir
4669 if crt.ChanDir().String() != "<-chan" {
4670 t.Errorf("chan dir: have %q, want %q", crt.ChanDir().String(), "<-chan")
4672 if cst.ChanDir().String() != "chan<-" {
4673 t.Errorf("chan dir: have %q, want %q", cst.ChanDir().String(), "chan<-")
4677 func TestChanOfGC(t *testing.T) {
4678 done := make(chan bool, 1)
4679 go func() {
4680 select {
4681 case <-done:
4682 case <-time.After(5 * time.Second):
4683 panic("deadlock in TestChanOfGC")
4687 defer func() {
4688 done <- true
4691 type T *uintptr
4692 tt := TypeOf(T(nil))
4693 ct := ChanOf(BothDir, tt)
4695 // NOTE: The garbage collector handles allocated channels specially,
4696 // so we have to save pointers to channels in x; the pointer code will
4697 // use the gc info in the newly constructed chan type.
4698 const n = 100
4699 var x []interface{}
4700 for i := 0; i < n; i++ {
4701 v := MakeChan(ct, n)
4702 for j := 0; j < n; j++ {
4703 p := new(uintptr)
4704 *p = uintptr(i*n + j)
4705 v.Send(ValueOf(p).Convert(tt))
4707 pv := New(ct)
4708 pv.Elem().Set(v)
4709 x = append(x, pv.Interface())
4711 runtime.GC()
4713 for i, xi := range x {
4714 v := ValueOf(xi).Elem()
4715 for j := 0; j < n; j++ {
4716 pv, _ := v.Recv()
4717 k := pv.Elem().Interface()
4718 if k != uintptr(i*n+j) {
4719 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
4725 func TestMapOf(t *testing.T) {
4726 // check construction and use of type not in binary
4727 type K string
4728 type V float64
4730 v := MakeMap(MapOf(TypeOf(K("")), TypeOf(V(0))))
4731 runtime.GC()
4732 v.SetMapIndex(ValueOf(K("a")), ValueOf(V(1)))
4733 runtime.GC()
4735 s := fmt.Sprint(v.Interface())
4736 want := "map[a:1]"
4737 if s != want {
4738 t.Errorf("constructed map = %s, want %s", s, want)
4741 // check that type already in binary is found
4742 checkSameType(t, Zero(MapOf(TypeOf(V(0)), TypeOf(K("")))).Interface(), map[V]K(nil))
4744 // check that invalid key type panics
4745 shouldPanic(func() { MapOf(TypeOf((func())(nil)), TypeOf(false)) })
4748 func TestMapOfGCKeys(t *testing.T) {
4749 type T *uintptr
4750 tt := TypeOf(T(nil))
4751 mt := MapOf(tt, TypeOf(false))
4753 // NOTE: The garbage collector handles allocated maps specially,
4754 // so we have to save pointers to maps in x; the pointer code will
4755 // use the gc info in the newly constructed map type.
4756 const n = 100
4757 var x []interface{}
4758 for i := 0; i < n; i++ {
4759 v := MakeMap(mt)
4760 for j := 0; j < n; j++ {
4761 p := new(uintptr)
4762 *p = uintptr(i*n + j)
4763 v.SetMapIndex(ValueOf(p).Convert(tt), ValueOf(true))
4765 pv := New(mt)
4766 pv.Elem().Set(v)
4767 x = append(x, pv.Interface())
4769 runtime.GC()
4771 for i, xi := range x {
4772 v := ValueOf(xi).Elem()
4773 var out []int
4774 for _, kv := range v.MapKeys() {
4775 out = append(out, int(kv.Elem().Interface().(uintptr)))
4777 sort.Ints(out)
4778 for j, k := range out {
4779 if k != i*n+j {
4780 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
4786 func TestMapOfGCValues(t *testing.T) {
4787 type T *uintptr
4788 tt := TypeOf(T(nil))
4789 mt := MapOf(TypeOf(1), tt)
4791 // NOTE: The garbage collector handles allocated maps specially,
4792 // so we have to save pointers to maps in x; the pointer code will
4793 // use the gc info in the newly constructed map type.
4794 const n = 100
4795 var x []interface{}
4796 for i := 0; i < n; i++ {
4797 v := MakeMap(mt)
4798 for j := 0; j < n; j++ {
4799 p := new(uintptr)
4800 *p = uintptr(i*n + j)
4801 v.SetMapIndex(ValueOf(j), ValueOf(p).Convert(tt))
4803 pv := New(mt)
4804 pv.Elem().Set(v)
4805 x = append(x, pv.Interface())
4807 runtime.GC()
4809 for i, xi := range x {
4810 v := ValueOf(xi).Elem()
4811 for j := 0; j < n; j++ {
4812 k := v.MapIndex(ValueOf(j)).Elem().Interface().(uintptr)
4813 if k != uintptr(i*n+j) {
4814 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
4820 func TestTypelinksSorted(t *testing.T) {
4821 var last string
4822 for i, n := range TypeLinks() {
4823 if n < last {
4824 t.Errorf("typelinks not sorted: %q [%d] > %q [%d]", last, i-1, n, i)
4826 last = n
4830 func TestFuncOf(t *testing.T) {
4831 // check construction and use of type not in binary
4832 type K string
4833 type V float64
4835 fn := func(args []Value) []Value {
4836 if len(args) != 1 {
4837 t.Errorf("args == %v, want exactly one arg", args)
4838 } else if args[0].Type() != TypeOf(K("")) {
4839 t.Errorf("args[0] is type %v, want %v", args[0].Type(), TypeOf(K("")))
4840 } else if args[0].String() != "gopher" {
4841 t.Errorf("args[0] = %q, want %q", args[0].String(), "gopher")
4843 return []Value{ValueOf(V(3.14))}
4845 v := MakeFunc(FuncOf([]Type{TypeOf(K(""))}, []Type{TypeOf(V(0))}, false), fn)
4847 outs := v.Call([]Value{ValueOf(K("gopher"))})
4848 if len(outs) != 1 {
4849 t.Fatalf("v.Call returned %v, want exactly one result", outs)
4850 } else if outs[0].Type() != TypeOf(V(0)) {
4851 t.Fatalf("c.Call[0] is type %v, want %v", outs[0].Type(), TypeOf(V(0)))
4853 f := outs[0].Float()
4854 if f != 3.14 {
4855 t.Errorf("constructed func returned %f, want %f", f, 3.14)
4858 // check that types already in binary are found
4859 type T1 int
4860 testCases := []struct {
4861 in, out []Type
4862 variadic bool
4863 want interface{}
4865 {in: []Type{TypeOf(T1(0))}, want: (func(T1))(nil)},
4866 {in: []Type{TypeOf(int(0))}, want: (func(int))(nil)},
4867 {in: []Type{SliceOf(TypeOf(int(0)))}, variadic: true, want: (func(...int))(nil)},
4868 {in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false)}, want: (func(int) bool)(nil)},
4869 {in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false), TypeOf("")}, want: (func(int) (bool, string))(nil)},
4871 for _, tt := range testCases {
4872 checkSameType(t, Zero(FuncOf(tt.in, tt.out, tt.variadic)).Interface(), tt.want)
4875 // check that variadic requires last element be a slice.
4876 FuncOf([]Type{TypeOf(1), TypeOf(""), SliceOf(TypeOf(false))}, nil, true)
4877 shouldPanic(func() { FuncOf([]Type{TypeOf(0), TypeOf(""), TypeOf(false)}, nil, true) })
4878 shouldPanic(func() { FuncOf(nil, nil, true) })
4881 type B1 struct {
4882 X int
4883 Y int
4884 Z int
4887 func BenchmarkFieldByName1(b *testing.B) {
4888 t := TypeOf(B1{})
4889 for i := 0; i < b.N; i++ {
4890 t.FieldByName("Z")
4894 func BenchmarkFieldByName2(b *testing.B) {
4895 t := TypeOf(S3{})
4896 for i := 0; i < b.N; i++ {
4897 t.FieldByName("B")
4901 type R0 struct {
4908 type R1 struct {
4915 type R2 R1
4916 type R3 R1
4917 type R4 R1
4919 type R5 struct {
4921 *R10
4922 *R11
4923 *R12
4926 type R6 R5
4927 type R7 R5
4928 type R8 R5
4930 type R9 struct {
4931 *R13
4932 *R14
4933 *R15
4934 *R16
4937 type R10 R9
4938 type R11 R9
4939 type R12 R9
4941 type R13 struct {
4942 *R17
4943 *R18
4944 *R19
4945 *R20
4948 type R14 R13
4949 type R15 R13
4950 type R16 R13
4952 type R17 struct {
4953 *R21
4954 *R22
4955 *R23
4956 *R24
4959 type R18 R17
4960 type R19 R17
4961 type R20 R17
4963 type R21 struct {
4964 X int
4967 type R22 R21
4968 type R23 R21
4969 type R24 R21
4971 func TestEmbed(t *testing.T) {
4972 typ := TypeOf(R0{})
4973 f, ok := typ.FieldByName("X")
4974 if ok {
4975 t.Fatalf(`FieldByName("X") should fail, returned %v`, f.Index)
4979 func BenchmarkFieldByName3(b *testing.B) {
4980 t := TypeOf(R0{})
4981 for i := 0; i < b.N; i++ {
4982 t.FieldByName("X")
4986 type S struct {
4987 i1 int64
4988 i2 int64
4991 func BenchmarkInterfaceBig(b *testing.B) {
4992 v := ValueOf(S{})
4993 for i := 0; i < b.N; i++ {
4994 v.Interface()
4996 b.StopTimer()
4999 func TestAllocsInterfaceBig(t *testing.T) {
5000 if testing.Short() {
5001 t.Skip("skipping malloc count in short mode")
5003 v := ValueOf(S{})
5004 if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
5005 t.Error("allocs:", allocs)
5009 func BenchmarkInterfaceSmall(b *testing.B) {
5010 v := ValueOf(int64(0))
5011 for i := 0; i < b.N; i++ {
5012 v.Interface()
5016 func TestAllocsInterfaceSmall(t *testing.T) {
5017 if testing.Short() {
5018 t.Skip("skipping malloc count in short mode")
5020 v := ValueOf(int64(0))
5021 if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
5022 t.Error("allocs:", allocs)
5026 // An exhaustive is a mechanism for writing exhaustive or stochastic tests.
5027 // The basic usage is:
5029 // for x.Next() {
5030 // ... code using x.Maybe() or x.Choice(n) to create test cases ...
5031 // }
5033 // Each iteration of the loop returns a different set of results, until all
5034 // possible result sets have been explored. It is okay for different code paths
5035 // to make different method call sequences on x, but there must be no
5036 // other source of non-determinism in the call sequences.
5038 // When faced with a new decision, x chooses randomly. Future explorations
5039 // of that path will choose successive values for the result. Thus, stopping
5040 // the loop after a fixed number of iterations gives somewhat stochastic
5041 // testing.
5043 // Example:
5045 // for x.Next() {
5046 // v := make([]bool, x.Choose(4))
5047 // for i := range v {
5048 // v[i] = x.Maybe()
5049 // }
5050 // fmt.Println(v)
5051 // }
5053 // prints (in some order):
5055 // []
5056 // [false]
5057 // [true]
5058 // [false false]
5059 // [false true]
5060 // ...
5061 // [true true]
5062 // [false false false]
5063 // ...
5064 // [true true true]
5065 // [false false false false]
5066 // ...
5067 // [true true true true]
5069 type exhaustive struct {
5070 r *rand.Rand
5071 pos int
5072 last []choice
5075 type choice struct {
5076 off int
5077 n int
5078 max int
5081 func (x *exhaustive) Next() bool {
5082 if x.r == nil {
5083 x.r = rand.New(rand.NewSource(time.Now().UnixNano()))
5085 x.pos = 0
5086 if x.last == nil {
5087 x.last = []choice{}
5088 return true
5090 for i := len(x.last) - 1; i >= 0; i-- {
5091 c := &x.last[i]
5092 if c.n+1 < c.max {
5093 c.n++
5094 x.last = x.last[:i+1]
5095 return true
5098 return false
5101 func (x *exhaustive) Choose(max int) int {
5102 if x.pos >= len(x.last) {
5103 x.last = append(x.last, choice{x.r.Intn(max), 0, max})
5105 c := &x.last[x.pos]
5106 x.pos++
5107 if c.max != max {
5108 panic("inconsistent use of exhaustive tester")
5110 return (c.n + c.off) % max
5113 func (x *exhaustive) Maybe() bool {
5114 return x.Choose(2) == 1
5117 func GCFunc(args []Value) []Value {
5118 runtime.GC()
5119 return []Value{}
5122 func TestReflectFuncTraceback(t *testing.T) {
5123 f := MakeFunc(TypeOf(func() {}), GCFunc)
5124 f.Call([]Value{})
5127 func TestReflectMethodTraceback(t *testing.T) {
5128 p := Point{3, 4}
5129 m := ValueOf(p).MethodByName("GCMethod")
5130 i := ValueOf(m.Interface()).Call([]Value{ValueOf(5)})[0].Int()
5131 if i != 8 {
5132 t.Errorf("Call returned %d; want 8", i)
5136 func TestBigZero(t *testing.T) {
5137 const size = 1 << 10
5138 var v [size]byte
5139 z := Zero(ValueOf(v).Type()).Interface().([size]byte)
5140 for i := 0; i < size; i++ {
5141 if z[i] != 0 {
5142 t.Fatalf("Zero object not all zero, index %d", i)
5147 func TestFieldByIndexNil(t *testing.T) {
5148 type P struct {
5149 F int
5151 type T struct {
5154 v := ValueOf(T{})
5156 v.FieldByName("P") // should be fine
5158 defer func() {
5159 if err := recover(); err == nil {
5160 t.Fatalf("no error")
5161 } else if !strings.Contains(fmt.Sprint(err), "nil pointer to embedded struct") {
5162 t.Fatalf(`err=%q, wanted error containing "nil pointer to embedded struct"`, err)
5165 v.FieldByName("F") // should panic
5167 t.Fatalf("did not panic")
5170 // Given
5171 // type Outer struct {
5172 // *Inner
5173 // ...
5174 // }
5175 // the compiler generates the implementation of (*Outer).M dispatching to the embedded Inner.
5176 // The implementation is logically:
5177 // func (p *Outer) M() {
5178 // (p.Inner).M()
5179 // }
5180 // but since the only change here is the replacement of one pointer receiver with another,
5181 // the actual generated code overwrites the original receiver with the p.Inner pointer and
5182 // then jumps to the M method expecting the *Inner receiver.
5184 // During reflect.Value.Call, we create an argument frame and the associated data structures
5185 // to describe it to the garbage collector, populate the frame, call reflect.call to
5186 // run a function call using that frame, and then copy the results back out of the frame.
5187 // The reflect.call function does a memmove of the frame structure onto the
5188 // stack (to set up the inputs), runs the call, and the memmoves the stack back to
5189 // the frame structure (to preserve the outputs).
5191 // Originally reflect.call did not distinguish inputs from outputs: both memmoves
5192 // were for the full stack frame. However, in the case where the called function was
5193 // one of these wrappers, the rewritten receiver is almost certainly a different type
5194 // than the original receiver. This is not a problem on the stack, where we use the
5195 // program counter to determine the type information and understand that
5196 // during (*Outer).M the receiver is an *Outer while during (*Inner).M the receiver in the same
5197 // memory word is now an *Inner. But in the statically typed argument frame created
5198 // by reflect, the receiver is always an *Outer. Copying the modified receiver pointer
5199 // off the stack into the frame will store an *Inner there, and then if a garbage collection
5200 // happens to scan that argument frame before it is discarded, it will scan the *Inner
5201 // memory as if it were an *Outer. If the two have different memory layouts, the
5202 // collection will interpret the memory incorrectly.
5204 // One such possible incorrect interpretation is to treat two arbitrary memory words
5205 // (Inner.P1 and Inner.P2 below) as an interface (Outer.R below). Because interpreting
5206 // an interface requires dereferencing the itab word, the misinterpretation will try to
5207 // deference Inner.P1, causing a crash during garbage collection.
5209 // This came up in a real program in issue 7725.
5211 type Outer struct {
5212 *Inner
5213 R io.Reader
5216 type Inner struct {
5217 X *Outer
5218 P1 uintptr
5219 P2 uintptr
5222 func (pi *Inner) M() {
5223 // Clear references to pi so that the only way the
5224 // garbage collection will find the pointer is in the
5225 // argument frame, typed as a *Outer.
5226 pi.X.Inner = nil
5228 // Set up an interface value that will cause a crash.
5229 // P1 = 1 is a non-zero, so the interface looks non-nil.
5230 // P2 = pi ensures that the data word points into the
5231 // allocated heap; if not the collection skips the interface
5232 // value as irrelevant, without dereferencing P1.
5233 pi.P1 = 1
5234 pi.P2 = uintptr(unsafe.Pointer(pi))
5237 func TestCallMethodJump(t *testing.T) {
5238 // In reflect.Value.Call, trigger a garbage collection after reflect.call
5239 // returns but before the args frame has been discarded.
5240 // This is a little clumsy but makes the failure repeatable.
5241 *CallGC = true
5243 p := &Outer{Inner: new(Inner)}
5244 p.Inner.X = p
5245 ValueOf(p).Method(0).Call(nil)
5247 // Stop garbage collecting during reflect.call.
5248 *CallGC = false
5251 func TestMakeFuncStackCopy(t *testing.T) {
5252 target := func(in []Value) []Value {
5253 runtime.GC()
5254 useStack(16)
5255 return []Value{ValueOf(9)}
5258 var concrete func(*int, int) int
5259 fn := MakeFunc(ValueOf(concrete).Type(), target)
5260 ValueOf(&concrete).Elem().Set(fn)
5261 x := concrete(nil, 7)
5262 if x != 9 {
5263 t.Errorf("have %#q want 9", x)
5267 // use about n KB of stack
5268 func useStack(n int) {
5269 if n == 0 {
5270 return
5272 var b [1024]byte // makes frame about 1KB
5273 useStack(n - 1 + int(b[99]))
5276 type Impl struct{}
5278 func (Impl) F() {}
5280 func TestValueString(t *testing.T) {
5281 rv := ValueOf(Impl{})
5282 if rv.String() != "<reflect_test.Impl Value>" {
5283 t.Errorf("ValueOf(Impl{}).String() = %q, want %q", rv.String(), "<reflect_test.Impl Value>")
5286 method := rv.Method(0)
5287 if method.String() != "<func() Value>" {
5288 t.Errorf("ValueOf(Impl{}).Method(0).String() = %q, want %q", method.String(), "<func() Value>")
5292 func TestInvalid(t *testing.T) {
5293 // Used to have inconsistency between IsValid() and Kind() != Invalid.
5294 type T struct{ v interface{} }
5296 v := ValueOf(T{}).Field(0)
5297 if v.IsValid() != true || v.Kind() != Interface {
5298 t.Errorf("field: IsValid=%v, Kind=%v, want true, Interface", v.IsValid(), v.Kind())
5300 v = v.Elem()
5301 if v.IsValid() != false || v.Kind() != Invalid {
5302 t.Errorf("field elem: IsValid=%v, Kind=%v, want false, Invalid", v.IsValid(), v.Kind())
5306 // Issue 8917.
5307 func TestLargeGCProg(t *testing.T) {
5308 fv := ValueOf(func([256]*byte) {})
5309 fv.Call([]Value{ValueOf([256]*byte{})})
5312 func fieldIndexRecover(t Type, i int) (recovered interface{}) {
5313 defer func() {
5314 recovered = recover()
5317 t.Field(i)
5318 return
5321 // Issue 15046.
5322 func TestTypeFieldOutOfRangePanic(t *testing.T) {
5323 typ := TypeOf(struct{ X int }{10})
5324 testIndices := [...]struct {
5325 i int
5326 mustPanic bool
5328 0: {-2, true},
5329 1: {0, false},
5330 2: {1, true},
5331 3: {1 << 10, true},
5333 for i, tt := range testIndices {
5334 recoveredErr := fieldIndexRecover(typ, tt.i)
5335 if tt.mustPanic {
5336 if recoveredErr == nil {
5337 t.Errorf("#%d: fieldIndex %d expected to panic", i, tt.i)
5339 } else {
5340 if recoveredErr != nil {
5341 t.Errorf("#%d: got err=%v, expected no panic", i, recoveredErr)
5347 // Issue 9179.
5348 func TestCallGC(t *testing.T) {
5349 f := func(a, b, c, d, e string) {
5351 g := func(in []Value) []Value {
5352 runtime.GC()
5353 return nil
5355 typ := ValueOf(f).Type()
5356 f2 := MakeFunc(typ, g).Interface().(func(string, string, string, string, string))
5357 f2("four", "five5", "six666", "seven77", "eight888")
5360 // Issue 18635 (function version).
5361 func TestKeepFuncLive(t *testing.T) {
5362 // Test that we keep makeFuncImpl live as long as it is
5363 // referenced on the stack.
5364 typ := TypeOf(func(i int) {})
5365 var f, g func(in []Value) []Value
5366 f = func(in []Value) []Value {
5367 clobber()
5368 i := int(in[0].Int())
5369 if i > 0 {
5370 // We can't use Value.Call here because
5371 // runtime.call* will keep the makeFuncImpl
5372 // alive. However, by converting it to an
5373 // interface value and calling that,
5374 // reflect.callReflect is the only thing that
5375 // can keep the makeFuncImpl live.
5377 // Alternate between f and g so that if we do
5378 // reuse the memory prematurely it's more
5379 // likely to get obviously corrupted.
5380 MakeFunc(typ, g).Interface().(func(i int))(i - 1)
5382 return nil
5384 g = func(in []Value) []Value {
5385 clobber()
5386 i := int(in[0].Int())
5387 MakeFunc(typ, f).Interface().(func(i int))(i)
5388 return nil
5390 MakeFunc(typ, f).Call([]Value{ValueOf(10)})
5393 // Issue 18635 (method version).
5394 type KeepMethodLive struct{}
5396 func (k KeepMethodLive) Method1(i int) {
5397 clobber()
5398 if i > 0 {
5399 ValueOf(k).MethodByName("Method2").Interface().(func(i int))(i - 1)
5403 func (k KeepMethodLive) Method2(i int) {
5404 clobber()
5405 ValueOf(k).MethodByName("Method1").Interface().(func(i int))(i)
5408 func TestKeepMethodLive(t *testing.T) {
5409 // Test that we keep methodValue live as long as it is
5410 // referenced on the stack.
5411 KeepMethodLive{}.Method1(10)
5414 // clobber tries to clobber unreachable memory.
5415 func clobber() {
5416 runtime.GC()
5417 for i := 1; i < 32; i++ {
5418 for j := 0; j < 10; j++ {
5419 obj := make([]*byte, i)
5420 sink = obj
5423 runtime.GC()
5426 type funcLayoutTest struct {
5427 rcvr, t Type
5428 size, argsize, retOffset uintptr
5429 stack []byte // pointer bitmap: 1 is pointer, 0 is scalar (or uninitialized)
5430 gc []byte
5433 var funcLayoutTests []funcLayoutTest
5435 func init() {
5436 var argAlign uintptr = PtrSize
5437 if runtime.GOARCH == "amd64p32" {
5438 argAlign = 2 * PtrSize
5440 roundup := func(x uintptr, a uintptr) uintptr {
5441 return (x + a - 1) / a * a
5444 funcLayoutTests = append(funcLayoutTests,
5445 funcLayoutTest{
5446 nil,
5447 ValueOf(func(a, b string) string { return "" }).Type(),
5448 6 * PtrSize,
5449 4 * PtrSize,
5450 4 * PtrSize,
5451 []byte{1, 0, 1},
5452 []byte{1, 0, 1, 0, 1},
5455 var r []byte
5456 if PtrSize == 4 {
5457 r = []byte{0, 0, 0, 1}
5458 } else {
5459 r = []byte{0, 0, 1}
5461 funcLayoutTests = append(funcLayoutTests,
5462 funcLayoutTest{
5463 nil,
5464 ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(),
5465 roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign),
5466 roundup(3*4, PtrSize) + PtrSize + 2,
5467 roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign),
5472 funcLayoutTests = append(funcLayoutTests,
5473 funcLayoutTest{
5474 nil,
5475 ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(),
5476 4 * PtrSize,
5477 4 * PtrSize,
5478 4 * PtrSize,
5479 []byte{1, 0, 1, 1},
5480 []byte{1, 0, 1, 1},
5483 type S struct {
5484 a, b uintptr
5485 c, d *byte
5487 funcLayoutTests = append(funcLayoutTests,
5488 funcLayoutTest{
5489 nil,
5490 ValueOf(func(a S) {}).Type(),
5491 4 * PtrSize,
5492 4 * PtrSize,
5493 4 * PtrSize,
5494 []byte{0, 0, 1, 1},
5495 []byte{0, 0, 1, 1},
5498 funcLayoutTests = append(funcLayoutTests,
5499 funcLayoutTest{
5500 ValueOf((*byte)(nil)).Type(),
5501 ValueOf(func(a uintptr, b *int) {}).Type(),
5502 roundup(3*PtrSize, argAlign),
5503 3 * PtrSize,
5504 roundup(3*PtrSize, argAlign),
5505 []byte{1, 0, 1},
5506 []byte{1, 0, 1},
5509 funcLayoutTests = append(funcLayoutTests,
5510 funcLayoutTest{
5511 nil,
5512 ValueOf(func(a uintptr) {}).Type(),
5513 roundup(PtrSize, argAlign),
5514 PtrSize,
5515 roundup(PtrSize, argAlign),
5516 []byte{},
5517 []byte{},
5520 funcLayoutTests = append(funcLayoutTests,
5521 funcLayoutTest{
5522 nil,
5523 ValueOf(func() uintptr { return 0 }).Type(),
5524 PtrSize,
5527 []byte{},
5528 []byte{},
5531 funcLayoutTests = append(funcLayoutTests,
5532 funcLayoutTest{
5533 ValueOf(uintptr(0)).Type(),
5534 ValueOf(func(a uintptr) {}).Type(),
5535 2 * PtrSize,
5536 2 * PtrSize,
5537 2 * PtrSize,
5538 []byte{1},
5539 []byte{1},
5540 // Note: this one is tricky, as the receiver is not a pointer. But we
5541 // pass the receiver by reference to the autogenerated pointer-receiver
5542 // version of the function.
5546 func TestFuncLayout(t *testing.T) {
5547 t.Skip("gccgo does not use funcLayout")
5548 for _, lt := range funcLayoutTests {
5549 typ, argsize, retOffset, stack, gc, ptrs := FuncLayout(lt.t, lt.rcvr)
5550 if typ.Size() != lt.size {
5551 t.Errorf("funcLayout(%v, %v).size=%d, want %d", lt.t, lt.rcvr, typ.Size(), lt.size)
5553 if argsize != lt.argsize {
5554 t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.t, lt.rcvr, argsize, lt.argsize)
5556 if retOffset != lt.retOffset {
5557 t.Errorf("funcLayout(%v, %v).retOffset=%d, want %d", lt.t, lt.rcvr, retOffset, lt.retOffset)
5559 if !bytes.Equal(stack, lt.stack) {
5560 t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.t, lt.rcvr, stack, lt.stack)
5562 if !bytes.Equal(gc, lt.gc) {
5563 t.Errorf("funcLayout(%v, %v).gc=%v, want %v", lt.t, lt.rcvr, gc, lt.gc)
5565 if ptrs && len(stack) == 0 || !ptrs && len(stack) > 0 {
5566 t.Errorf("funcLayout(%v, %v) pointers flag=%v, want %v", lt.t, lt.rcvr, ptrs, !ptrs)
5571 func verifyGCBits(t *testing.T, typ Type, bits []byte) {
5572 heapBits := GCBits(New(typ).Interface())
5573 if !bytes.Equal(heapBits, bits) {
5574 t.Errorf("heapBits incorrect for %v\nhave %v\nwant %v", typ, heapBits, bits)
5578 func verifyGCBitsSlice(t *testing.T, typ Type, cap int, bits []byte) {
5579 // Creating a slice causes the runtime to repeat a bitmap,
5580 // which exercises a different path from making the compiler
5581 // repeat a bitmap for a small array or executing a repeat in
5582 // a GC program.
5583 val := MakeSlice(typ, 0, cap)
5584 data := NewAt(ArrayOf(cap, typ), unsafe.Pointer(val.Pointer()))
5585 heapBits := GCBits(data.Interface())
5586 // Repeat the bitmap for the slice size, trimming scalars in
5587 // the last element.
5588 bits = rep(cap, bits)
5589 for len(bits) > 2 && bits[len(bits)-1] == 0 {
5590 bits = bits[:len(bits)-1]
5592 if len(bits) == 2 && bits[0] == 0 && bits[1] == 0 {
5593 bits = bits[:0]
5595 if !bytes.Equal(heapBits, bits) {
5596 t.Errorf("heapBits incorrect for make(%v, 0, %v)\nhave %v\nwant %v", typ, cap, heapBits, bits)
5600 func TestGCBits(t *testing.T) {
5601 t.Skip("gccgo does not use gcbits yet")
5603 verifyGCBits(t, TypeOf((*byte)(nil)), []byte{1})
5605 // Building blocks for types seen by the compiler (like [2]Xscalar).
5606 // The compiler will create the type structures for the derived types,
5607 // including their GC metadata.
5608 type Xscalar struct{ x uintptr }
5609 type Xptr struct{ x *byte }
5610 type Xptrscalar struct {
5611 *byte
5612 uintptr
5614 type Xscalarptr struct {
5615 uintptr
5616 *byte
5618 type Xbigptrscalar struct {
5619 _ [100]*byte
5620 _ [100]uintptr
5623 var Tscalar, Tint64, Tptr, Tscalarptr, Tptrscalar, Tbigptrscalar Type
5625 // Building blocks for types constructed by reflect.
5626 // This code is in a separate block so that code below
5627 // cannot accidentally refer to these.
5628 // The compiler must NOT see types derived from these
5629 // (for example, [2]Scalar must NOT appear in the program),
5630 // or else reflect will use it instead of having to construct one.
5631 // The goal is to test the construction.
5632 type Scalar struct{ x uintptr }
5633 type Ptr struct{ x *byte }
5634 type Ptrscalar struct {
5635 *byte
5636 uintptr
5638 type Scalarptr struct {
5639 uintptr
5640 *byte
5642 type Bigptrscalar struct {
5643 _ [100]*byte
5644 _ [100]uintptr
5646 type Int64 int64
5647 Tscalar = TypeOf(Scalar{})
5648 Tint64 = TypeOf(Int64(0))
5649 Tptr = TypeOf(Ptr{})
5650 Tscalarptr = TypeOf(Scalarptr{})
5651 Tptrscalar = TypeOf(Ptrscalar{})
5652 Tbigptrscalar = TypeOf(Bigptrscalar{})
5655 empty := []byte{}
5657 verifyGCBits(t, TypeOf(Xscalar{}), empty)
5658 verifyGCBits(t, Tscalar, empty)
5659 verifyGCBits(t, TypeOf(Xptr{}), lit(1))
5660 verifyGCBits(t, Tptr, lit(1))
5661 verifyGCBits(t, TypeOf(Xscalarptr{}), lit(0, 1))
5662 verifyGCBits(t, Tscalarptr, lit(0, 1))
5663 verifyGCBits(t, TypeOf(Xptrscalar{}), lit(1))
5664 verifyGCBits(t, Tptrscalar, lit(1))
5666 verifyGCBits(t, TypeOf([0]Xptr{}), empty)
5667 verifyGCBits(t, ArrayOf(0, Tptr), empty)
5668 verifyGCBits(t, TypeOf([1]Xptrscalar{}), lit(1))
5669 verifyGCBits(t, ArrayOf(1, Tptrscalar), lit(1))
5670 verifyGCBits(t, TypeOf([2]Xscalar{}), empty)
5671 verifyGCBits(t, ArrayOf(2, Tscalar), empty)
5672 verifyGCBits(t, TypeOf([10000]Xscalar{}), empty)
5673 verifyGCBits(t, ArrayOf(10000, Tscalar), empty)
5674 verifyGCBits(t, TypeOf([2]Xptr{}), lit(1, 1))
5675 verifyGCBits(t, ArrayOf(2, Tptr), lit(1, 1))
5676 verifyGCBits(t, TypeOf([10000]Xptr{}), rep(10000, lit(1)))
5677 verifyGCBits(t, ArrayOf(10000, Tptr), rep(10000, lit(1)))
5678 verifyGCBits(t, TypeOf([2]Xscalarptr{}), lit(0, 1, 0, 1))
5679 verifyGCBits(t, ArrayOf(2, Tscalarptr), lit(0, 1, 0, 1))
5680 verifyGCBits(t, TypeOf([10000]Xscalarptr{}), rep(10000, lit(0, 1)))
5681 verifyGCBits(t, ArrayOf(10000, Tscalarptr), rep(10000, lit(0, 1)))
5682 verifyGCBits(t, TypeOf([2]Xptrscalar{}), lit(1, 0, 1))
5683 verifyGCBits(t, ArrayOf(2, Tptrscalar), lit(1, 0, 1))
5684 verifyGCBits(t, TypeOf([10000]Xptrscalar{}), rep(10000, lit(1, 0)))
5685 verifyGCBits(t, ArrayOf(10000, Tptrscalar), rep(10000, lit(1, 0)))
5686 verifyGCBits(t, TypeOf([1][10000]Xptrscalar{}), rep(10000, lit(1, 0)))
5687 verifyGCBits(t, ArrayOf(1, ArrayOf(10000, Tptrscalar)), rep(10000, lit(1, 0)))
5688 verifyGCBits(t, TypeOf([2][10000]Xptrscalar{}), rep(2*10000, lit(1, 0)))
5689 verifyGCBits(t, ArrayOf(2, ArrayOf(10000, Tptrscalar)), rep(2*10000, lit(1, 0)))
5690 verifyGCBits(t, TypeOf([4]Xbigptrscalar{}), join(rep(3, join(rep(100, lit(1)), rep(100, lit(0)))), rep(100, lit(1))))
5691 verifyGCBits(t, ArrayOf(4, Tbigptrscalar), join(rep(3, join(rep(100, lit(1)), rep(100, lit(0)))), rep(100, lit(1))))
5693 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 0, empty)
5694 verifyGCBitsSlice(t, SliceOf(Tptr), 0, empty)
5695 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 1, lit(1))
5696 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 1, lit(1))
5697 verifyGCBitsSlice(t, TypeOf([]Xscalar{}), 2, lit(0))
5698 verifyGCBitsSlice(t, SliceOf(Tscalar), 2, lit(0))
5699 verifyGCBitsSlice(t, TypeOf([]Xscalar{}), 10000, lit(0))
5700 verifyGCBitsSlice(t, SliceOf(Tscalar), 10000, lit(0))
5701 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 2, lit(1))
5702 verifyGCBitsSlice(t, SliceOf(Tptr), 2, lit(1))
5703 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 10000, lit(1))
5704 verifyGCBitsSlice(t, SliceOf(Tptr), 10000, lit(1))
5705 verifyGCBitsSlice(t, TypeOf([]Xscalarptr{}), 2, lit(0, 1))
5706 verifyGCBitsSlice(t, SliceOf(Tscalarptr), 2, lit(0, 1))
5707 verifyGCBitsSlice(t, TypeOf([]Xscalarptr{}), 10000, lit(0, 1))
5708 verifyGCBitsSlice(t, SliceOf(Tscalarptr), 10000, lit(0, 1))
5709 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 2, lit(1, 0))
5710 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 2, lit(1, 0))
5711 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 10000, lit(1, 0))
5712 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 10000, lit(1, 0))
5713 verifyGCBitsSlice(t, TypeOf([][10000]Xptrscalar{}), 1, rep(10000, lit(1, 0)))
5714 verifyGCBitsSlice(t, SliceOf(ArrayOf(10000, Tptrscalar)), 1, rep(10000, lit(1, 0)))
5715 verifyGCBitsSlice(t, TypeOf([][10000]Xptrscalar{}), 2, rep(10000, lit(1, 0)))
5716 verifyGCBitsSlice(t, SliceOf(ArrayOf(10000, Tptrscalar)), 2, rep(10000, lit(1, 0)))
5717 verifyGCBitsSlice(t, TypeOf([]Xbigptrscalar{}), 4, join(rep(100, lit(1)), rep(100, lit(0))))
5718 verifyGCBitsSlice(t, SliceOf(Tbigptrscalar), 4, join(rep(100, lit(1)), rep(100, lit(0))))
5720 verifyGCBits(t, TypeOf((chan [100]Xscalar)(nil)), lit(1))
5721 verifyGCBits(t, ChanOf(BothDir, ArrayOf(100, Tscalar)), lit(1))
5723 verifyGCBits(t, TypeOf((func([10000]Xscalarptr))(nil)), lit(1))
5724 verifyGCBits(t, FuncOf([]Type{ArrayOf(10000, Tscalarptr)}, nil, false), lit(1))
5726 verifyGCBits(t, TypeOf((map[[10000]Xscalarptr]Xscalar)(nil)), lit(1))
5727 verifyGCBits(t, MapOf(ArrayOf(10000, Tscalarptr), Tscalar), lit(1))
5729 verifyGCBits(t, TypeOf((*[10000]Xscalar)(nil)), lit(1))
5730 verifyGCBits(t, PtrTo(ArrayOf(10000, Tscalar)), lit(1))
5732 verifyGCBits(t, TypeOf(([][10000]Xscalar)(nil)), lit(1))
5733 verifyGCBits(t, SliceOf(ArrayOf(10000, Tscalar)), lit(1))
5735 hdr := make([]byte, 8/PtrSize)
5737 verifyMapBucket := func(t *testing.T, k, e Type, m interface{}, want []byte) {
5738 verifyGCBits(t, MapBucketOf(k, e), want)
5739 verifyGCBits(t, CachedBucketOf(TypeOf(m)), want)
5741 verifyMapBucket(t,
5742 Tscalar, Tptr,
5743 map[Xscalar]Xptr(nil),
5744 join(hdr, rep(8, lit(0)), rep(8, lit(1)), lit(1)))
5745 verifyMapBucket(t,
5746 Tscalarptr, Tptr,
5747 map[Xscalarptr]Xptr(nil),
5748 join(hdr, rep(8, lit(0, 1)), rep(8, lit(1)), lit(1)))
5749 verifyMapBucket(t, Tint64, Tptr,
5750 map[int64]Xptr(nil),
5751 join(hdr, rep(8, rep(8/PtrSize, lit(0))), rep(8, lit(1)), naclpad(), lit(1)))
5752 verifyMapBucket(t,
5753 Tscalar, Tscalar,
5754 map[Xscalar]Xscalar(nil),
5755 empty)
5756 verifyMapBucket(t,
5757 ArrayOf(2, Tscalarptr), ArrayOf(3, Tptrscalar),
5758 map[[2]Xscalarptr][3]Xptrscalar(nil),
5759 join(hdr, rep(8*2, lit(0, 1)), rep(8*3, lit(1, 0)), lit(1)))
5760 verifyMapBucket(t,
5761 ArrayOf(64/PtrSize, Tscalarptr), ArrayOf(64/PtrSize, Tptrscalar),
5762 map[[64 / PtrSize]Xscalarptr][64 / PtrSize]Xptrscalar(nil),
5763 join(hdr, rep(8*64/PtrSize, lit(0, 1)), rep(8*64/PtrSize, lit(1, 0)), lit(1)))
5764 verifyMapBucket(t,
5765 ArrayOf(64/PtrSize+1, Tscalarptr), ArrayOf(64/PtrSize, Tptrscalar),
5766 map[[64/PtrSize + 1]Xscalarptr][64 / PtrSize]Xptrscalar(nil),
5767 join(hdr, rep(8, lit(1)), rep(8*64/PtrSize, lit(1, 0)), lit(1)))
5768 verifyMapBucket(t,
5769 ArrayOf(64/PtrSize, Tscalarptr), ArrayOf(64/PtrSize+1, Tptrscalar),
5770 map[[64 / PtrSize]Xscalarptr][64/PtrSize + 1]Xptrscalar(nil),
5771 join(hdr, rep(8*64/PtrSize, lit(0, 1)), rep(8, lit(1)), lit(1)))
5772 verifyMapBucket(t,
5773 ArrayOf(64/PtrSize+1, Tscalarptr), ArrayOf(64/PtrSize+1, Tptrscalar),
5774 map[[64/PtrSize + 1]Xscalarptr][64/PtrSize + 1]Xptrscalar(nil),
5775 join(hdr, rep(8, lit(1)), rep(8, lit(1)), lit(1)))
5778 func naclpad() []byte {
5779 if runtime.GOARCH == "amd64p32" {
5780 return lit(0)
5782 return nil
5785 func rep(n int, b []byte) []byte { return bytes.Repeat(b, n) }
5786 func join(b ...[]byte) []byte { return bytes.Join(b, nil) }
5787 func lit(x ...byte) []byte { return x }
5789 func TestTypeOfTypeOf(t *testing.T) {
5790 // Check that all the type constructors return concrete *rtype implementations.
5791 // It's difficult to test directly because the reflect package is only at arm's length.
5792 // The easiest thing to do is just call a function that crashes if it doesn't get an *rtype.
5793 check := func(name string, typ Type) {
5794 if underlying := TypeOf(typ).String(); underlying != "*reflect.rtype" {
5795 t.Errorf("%v returned %v, not *reflect.rtype", name, underlying)
5799 type T struct{ int }
5800 check("TypeOf", TypeOf(T{}))
5802 check("ArrayOf", ArrayOf(10, TypeOf(T{})))
5803 check("ChanOf", ChanOf(BothDir, TypeOf(T{})))
5804 check("FuncOf", FuncOf([]Type{TypeOf(T{})}, nil, false))
5805 check("MapOf", MapOf(TypeOf(T{}), TypeOf(T{})))
5806 check("PtrTo", PtrTo(TypeOf(T{})))
5807 check("SliceOf", SliceOf(TypeOf(T{})))
5810 type XM struct{}
5812 func (*XM) String() string { return "" }
5814 func TestPtrToMethods(t *testing.T) {
5815 var y struct{ XM }
5816 yp := New(TypeOf(y)).Interface()
5817 _, ok := yp.(fmt.Stringer)
5818 if !ok {
5819 t.Fatal("does not implement Stringer, but should")
5823 func TestMapAlloc(t *testing.T) {
5824 if runtime.Compiler == "gccgo" {
5825 t.Skip("skipping on gccgo until we have escape analysis")
5827 m := ValueOf(make(map[int]int, 10))
5828 k := ValueOf(5)
5829 v := ValueOf(7)
5830 allocs := testing.AllocsPerRun(100, func() {
5831 m.SetMapIndex(k, v)
5833 if allocs > 0.5 {
5834 t.Errorf("allocs per map assignment: want 0 got %f", allocs)
5838 func TestChanAlloc(t *testing.T) {
5839 if runtime.Compiler == "gccgo" {
5840 t.Skip("skipping on gccgo until we have escape analysis")
5842 // Note: for a chan int, the return Value must be allocated, so we
5843 // use a chan *int instead.
5844 c := ValueOf(make(chan *int, 1))
5845 v := ValueOf(new(int))
5846 allocs := testing.AllocsPerRun(100, func() {
5847 c.Send(v)
5848 _, _ = c.Recv()
5850 if allocs < 0.5 || allocs > 1.5 {
5851 t.Errorf("allocs per chan send/recv: want 1 got %f", allocs)
5853 // Note: there is one allocation in reflect.recv which seems to be
5854 // a limitation of escape analysis. If that is ever fixed the
5855 // allocs < 0.5 condition will trigger and this test should be fixed.
5858 type TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678 int
5860 type nameTest struct {
5861 v interface{}
5862 want string
5865 var nameTests = []nameTest{
5866 {(*int32)(nil), "int32"},
5867 {(*D1)(nil), "D1"},
5868 {(*[]D1)(nil), ""},
5869 {(*chan D1)(nil), ""},
5870 {(*func() D1)(nil), ""},
5871 {(*<-chan D1)(nil), ""},
5872 {(*chan<- D1)(nil), ""},
5873 {(*interface{})(nil), ""},
5874 {(*interface {
5876 })(nil), ""},
5877 {(*TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678)(nil), "TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678"},
5880 func TestNames(t *testing.T) {
5881 for _, test := range nameTests {
5882 typ := TypeOf(test.v).Elem()
5883 if got := typ.Name(); got != test.want {
5884 t.Errorf("%v Name()=%q, want %q", typ, got, test.want)
5890 gccgo doesn't really record whether a type is exported.
5891 It's not in the reflect API anyhow.
5893 func TestExported(t *testing.T) {
5894 type ΦExported struct{}
5895 type φUnexported struct{}
5896 type BigP *big
5897 type P int
5898 type p *P
5899 type P2 p
5900 type p3 p
5902 type exportTest struct {
5903 v interface{}
5904 want bool
5906 exportTests := []exportTest{
5907 {D1{}, true},
5908 {(*D1)(nil), true},
5909 {big{}, false},
5910 {(*big)(nil), false},
5911 {(BigP)(nil), true},
5912 {(*BigP)(nil), true},
5913 {ΦExported{}, true},
5914 {φUnexported{}, false},
5915 {P(0), true},
5916 {(p)(nil), false},
5917 {(P2)(nil), true},
5918 {(p3)(nil), false},
5921 for i, test := range exportTests {
5922 typ := TypeOf(test.v)
5923 if got := IsExported(typ); got != test.want {
5924 t.Errorf("%d: %s exported=%v, want %v", i, typ.Name(), got, test.want)
5930 type embed struct {
5931 EmbedWithUnexpMeth
5935 func TestNameBytesAreAligned(t *testing.T) {
5936 typ := TypeOf(embed{})
5937 b := FirstMethodNameBytes(typ)
5938 v := uintptr(unsafe.Pointer(b))
5939 if v%unsafe.Alignof((*byte)(nil)) != 0 {
5940 t.Errorf("reflect.name.bytes pointer is not aligned: %x", v)
5945 func TestTypeStrings(t *testing.T) {
5946 type stringTest struct {
5947 typ Type
5948 want string
5950 stringTests := []stringTest{
5951 {TypeOf(func(int) {}), "func(int)"},
5952 {FuncOf([]Type{TypeOf(int(0))}, nil, false), "func(int)"},
5953 {TypeOf(XM{}), "reflect_test.XM"},
5954 {TypeOf(new(XM)), "*reflect_test.XM"},
5955 {TypeOf(new(XM).String), "func() string"},
5956 {TypeOf(new(XM)).Method(0).Type, "func(*reflect_test.XM) string"},
5957 {ChanOf(3, TypeOf(XM{})), "chan reflect_test.XM"},
5958 {MapOf(TypeOf(int(0)), TypeOf(XM{})), "map[int]reflect_test.XM"},
5961 for i, test := range stringTests {
5962 if got, want := test.typ.String(), test.want; got != want {
5963 t.Errorf("type %d String()=%q, want %q", i, got, want)
5969 gccgo does not have resolveReflectName.
5971 func TestOffsetLock(t *testing.T) {
5972 var wg sync.WaitGroup
5973 for i := 0; i < 4; i++ {
5974 i := i
5975 wg.Add(1)
5976 go func() {
5977 for j := 0; j < 50; j++ {
5978 ResolveReflectName(fmt.Sprintf("OffsetLockName:%d:%d", i, j))
5980 wg.Done()
5983 wg.Wait()
5987 func BenchmarkNew(b *testing.B) {
5988 v := TypeOf(XM{})
5989 for i := 0; i < b.N; i++ {
5990 New(v)
5994 func TestSwapper(t *testing.T) {
5995 type I int
5996 var a, b, c I
5997 type pair struct {
5998 x, y int
6000 type pairPtr struct {
6001 x, y int
6002 p *I
6004 type S string
6006 tests := []struct {
6007 in interface{}
6008 i, j int
6009 want interface{}
6012 in: []int{1, 20, 300},
6013 i: 0,
6014 j: 2,
6015 want: []int{300, 20, 1},
6018 in: []uintptr{1, 20, 300},
6019 i: 0,
6020 j: 2,
6021 want: []uintptr{300, 20, 1},
6024 in: []int16{1, 20, 300},
6025 i: 0,
6026 j: 2,
6027 want: []int16{300, 20, 1},
6030 in: []int8{1, 20, 100},
6031 i: 0,
6032 j: 2,
6033 want: []int8{100, 20, 1},
6036 in: []*I{&a, &b, &c},
6037 i: 0,
6038 j: 2,
6039 want: []*I{&c, &b, &a},
6042 in: []string{"eric", "sergey", "larry"},
6043 i: 0,
6044 j: 2,
6045 want: []string{"larry", "sergey", "eric"},
6048 in: []S{"eric", "sergey", "larry"},
6049 i: 0,
6050 j: 2,
6051 want: []S{"larry", "sergey", "eric"},
6054 in: []pair{{1, 2}, {3, 4}, {5, 6}},
6055 i: 0,
6056 j: 2,
6057 want: []pair{{5, 6}, {3, 4}, {1, 2}},
6060 in: []pairPtr{{1, 2, &a}, {3, 4, &b}, {5, 6, &c}},
6061 i: 0,
6062 j: 2,
6063 want: []pairPtr{{5, 6, &c}, {3, 4, &b}, {1, 2, &a}},
6066 for i, tt := range tests {
6067 inStr := fmt.Sprint(tt.in)
6068 Swapper(tt.in)(tt.i, tt.j)
6069 if !DeepEqual(tt.in, tt.want) {
6070 t.Errorf("%d. swapping %v and %v of %v = %v; want %v", i, tt.i, tt.j, inStr, tt.in, tt.want)
6075 // TestUnaddressableField tests that the reflect package will not allow
6076 // a type from another package to be used as a named type with an
6077 // unexported field.
6079 // This ensures that unexported fields cannot be modified by other packages.
6080 func TestUnaddressableField(t *testing.T) {
6081 var b Buffer // type defined in reflect, a different package
6082 var localBuffer struct {
6083 buf []byte
6085 lv := ValueOf(&localBuffer).Elem()
6086 rv := ValueOf(b)
6087 shouldPanic(func() {
6088 lv.Set(rv)