@@ -2776,32 +2776,58 @@ func TestSetBytes(t *testing.T) {
2776
2776
type Private struct {
2777
2777
x int
2778
2778
y * * int
2779
+ Z int
2779
2780
}
2780
2781
2781
2782
func (p * Private ) m () {
2782
2783
}
2783
2784
2785
+ type private struct {
2786
+ Z int
2787
+ z int
2788
+ S string
2789
+ A [1 ]Private
2790
+ T []Private
2791
+ }
2792
+
2793
+ func (p * private ) P () {
2794
+ }
2795
+
2784
2796
type Public struct {
2785
2797
X int
2786
2798
Y * * int
2799
+ private
2787
2800
}
2788
2801
2789
2802
func (p * Public ) M () {
2790
2803
}
2791
2804
2792
2805
func TestUnexported (t * testing.T ) {
2793
2806
var pub Public
2807
+ pub .S = "S"
2808
+ pub .T = pub .A [:]
2794
2809
v := ValueOf (& pub )
2795
2810
isValid (v .Elem ().Field (0 ))
2796
2811
isValid (v .Elem ().Field (1 ))
2812
+ isValid (v .Elem ().Field (2 ))
2797
2813
isValid (v .Elem ().FieldByName ("X" ))
2798
2814
isValid (v .Elem ().FieldByName ("Y" ))
2815
+ isValid (v .Elem ().FieldByName ("Z" ))
2799
2816
isValid (v .Type ().Method (0 ).Func )
2817
+ m , _ := v .Type ().MethodByName ("M" )
2818
+ isValid (m .Func )
2819
+ m , _ = v .Type ().MethodByName ("P" )
2820
+ isValid (m .Func )
2800
2821
isNonNil (v .Elem ().Field (0 ).Interface ())
2801
2822
isNonNil (v .Elem ().Field (1 ).Interface ())
2823
+ isNonNil (v .Elem ().Field (2 ).Field (2 ).Index (0 ))
2802
2824
isNonNil (v .Elem ().FieldByName ("X" ).Interface ())
2803
2825
isNonNil (v .Elem ().FieldByName ("Y" ).Interface ())
2826
+ isNonNil (v .Elem ().FieldByName ("Z" ).Interface ())
2827
+ isNonNil (v .Elem ().FieldByName ("S" ).Index (0 ).Interface ())
2804
2828
isNonNil (v .Type ().Method (0 ).Func .Interface ())
2829
+ m , _ = v .Type ().MethodByName ("P" )
2830
+ isNonNil (m .Func .Interface ())
2805
2831
2806
2832
var priv Private
2807
2833
v = ValueOf (& priv )
@@ -2817,6 +2843,170 @@ func TestUnexported(t *testing.T) {
2817
2843
shouldPanic (func () { v .Type ().Method (0 ).Func .Interface () })
2818
2844
}
2819
2845
2846
+ func TestSetPanic (t * testing.T ) {
2847
+ ok := func (f func ()) { f () }
2848
+ bad := shouldPanic
2849
+ clear := func (v Value ) { v .Set (Zero (v .Type ())) }
2850
+
2851
+ type t0 struct {
2852
+ W int
2853
+ }
2854
+
2855
+ type t1 struct {
2856
+ Y int
2857
+ t0
2858
+ }
2859
+
2860
+ type T2 struct {
2861
+ Z int
2862
+ namedT0 t0
2863
+ }
2864
+
2865
+ type T struct {
2866
+ X int
2867
+ t1
2868
+ T2
2869
+ NamedT1 t1
2870
+ NamedT2 T2
2871
+ namedT1 t1
2872
+ namedT2 T2
2873
+ }
2874
+
2875
+ // not addressable
2876
+ v := ValueOf (T {})
2877
+ bad (func () { clear (v .Field (0 )) }) // .X
2878
+ bad (func () { clear (v .Field (1 )) }) // .t1
2879
+ bad (func () { clear (v .Field (1 ).Field (0 )) }) // .t1.Y
2880
+ bad (func () { clear (v .Field (1 ).Field (1 )) }) // .t1.t0
2881
+ bad (func () { clear (v .Field (1 ).Field (1 ).Field (0 )) }) // .t1.t0.W
2882
+ bad (func () { clear (v .Field (2 )) }) // .T2
2883
+ bad (func () { clear (v .Field (2 ).Field (0 )) }) // .T2.Z
2884
+ bad (func () { clear (v .Field (2 ).Field (1 )) }) // .T2.namedT0
2885
+ bad (func () { clear (v .Field (2 ).Field (1 ).Field (0 )) }) // .T2.namedT0.W
2886
+ bad (func () { clear (v .Field (3 )) }) // .NamedT1
2887
+ bad (func () { clear (v .Field (3 ).Field (0 )) }) // .NamedT1.Y
2888
+ bad (func () { clear (v .Field (3 ).Field (1 )) }) // .NamedT1.t0
2889
+ bad (func () { clear (v .Field (3 ).Field (1 ).Field (0 )) }) // .NamedT1.t0.W
2890
+ bad (func () { clear (v .Field (4 )) }) // .NamedT2
2891
+ bad (func () { clear (v .Field (4 ).Field (0 )) }) // .NamedT2.Z
2892
+ bad (func () { clear (v .Field (4 ).Field (1 )) }) // .NamedT2.namedT0
2893
+ bad (func () { clear (v .Field (4 ).Field (1 ).Field (0 )) }) // .NamedT2.namedT0.W
2894
+ bad (func () { clear (v .Field (5 )) }) // .namedT1
2895
+ bad (func () { clear (v .Field (5 ).Field (0 )) }) // .namedT1.Y
2896
+ bad (func () { clear (v .Field (5 ).Field (1 )) }) // .namedT1.t0
2897
+ bad (func () { clear (v .Field (5 ).Field (1 ).Field (0 )) }) // .namedT1.t0.W
2898
+ bad (func () { clear (v .Field (6 )) }) // .namedT2
2899
+ bad (func () { clear (v .Field (6 ).Field (0 )) }) // .namedT2.Z
2900
+ bad (func () { clear (v .Field (6 ).Field (1 )) }) // .namedT2.namedT0
2901
+ bad (func () { clear (v .Field (6 ).Field (1 ).Field (0 )) }) // .namedT2.namedT0.W
2902
+
2903
+ // addressable
2904
+ v = ValueOf (& T {}).Elem ()
2905
+ ok (func () { clear (v .Field (0 )) }) // .X
2906
+ bad (func () { clear (v .Field (1 )) }) // .t1
2907
+ ok (func () { clear (v .Field (1 ).Field (0 )) }) // .t1.Y
2908
+ bad (func () { clear (v .Field (1 ).Field (1 )) }) // .t1.t0
2909
+ ok (func () { clear (v .Field (1 ).Field (1 ).Field (0 )) }) // .t1.t0.W
2910
+ ok (func () { clear (v .Field (2 )) }) // .T2
2911
+ ok (func () { clear (v .Field (2 ).Field (0 )) }) // .T2.Z
2912
+ bad (func () { clear (v .Field (2 ).Field (1 )) }) // .T2.namedT0
2913
+ bad (func () { clear (v .Field (2 ).Field (1 ).Field (0 )) }) // .T2.namedT0.W
2914
+ ok (func () { clear (v .Field (3 )) }) // .NamedT1
2915
+ ok (func () { clear (v .Field (3 ).Field (0 )) }) // .NamedT1.Y
2916
+ bad (func () { clear (v .Field (3 ).Field (1 )) }) // .NamedT1.t0
2917
+ ok (func () { clear (v .Field (3 ).Field (1 ).Field (0 )) }) // .NamedT1.t0.W
2918
+ ok (func () { clear (v .Field (4 )) }) // .NamedT2
2919
+ ok (func () { clear (v .Field (4 ).Field (0 )) }) // .NamedT2.Z
2920
+ bad (func () { clear (v .Field (4 ).Field (1 )) }) // .NamedT2.namedT0
2921
+ bad (func () { clear (v .Field (4 ).Field (1 ).Field (0 )) }) // .NamedT2.namedT0.W
2922
+ bad (func () { clear (v .Field (5 )) }) // .namedT1
2923
+ bad (func () { clear (v .Field (5 ).Field (0 )) }) // .namedT1.Y
2924
+ bad (func () { clear (v .Field (5 ).Field (1 )) }) // .namedT1.t0
2925
+ bad (func () { clear (v .Field (5 ).Field (1 ).Field (0 )) }) // .namedT1.t0.W
2926
+ bad (func () { clear (v .Field (6 )) }) // .namedT2
2927
+ bad (func () { clear (v .Field (6 ).Field (0 )) }) // .namedT2.Z
2928
+ bad (func () { clear (v .Field (6 ).Field (1 )) }) // .namedT2.namedT0
2929
+ bad (func () { clear (v .Field (6 ).Field (1 ).Field (0 )) }) // .namedT2.namedT0.W
2930
+ }
2931
+
2932
+ type timp int
2933
+
2934
+ func (t timp ) W () {}
2935
+ func (t timp ) Y () {}
2936
+ func (t timp ) w () {}
2937
+ func (t timp ) y () {}
2938
+
2939
+ func TestCallPanic (t * testing.T ) {
2940
+ type t0 interface {
2941
+ W ()
2942
+ w ()
2943
+ }
2944
+ type T1 interface {
2945
+ Y ()
2946
+ y ()
2947
+ }
2948
+ type T2 struct {
2949
+ T1
2950
+ t0
2951
+ }
2952
+ type T struct {
2953
+ t0 // 0
2954
+ T1 // 1
2955
+
2956
+ NamedT0 t0 // 2
2957
+ NamedT1 T1 // 3
2958
+ NamedT2 T2 // 4
2959
+
2960
+ namedT0 t0 // 5
2961
+ namedT1 T1 // 6
2962
+ namedT2 T2 // 7
2963
+ }
2964
+ ok := func (f func ()) { f () }
2965
+ bad := shouldPanic
2966
+ call := func (v Value ) { v .Call (nil ) }
2967
+
2968
+ i := timp (0 )
2969
+ v := ValueOf (T {i , i , i , i , T2 {i , i }, i , i , T2 {i , i }})
2970
+ ok (func () { call (v .Field (0 ).Method (0 )) }) // .t0.W
2971
+ ok (func () { call (v .Field (0 ).Elem ().Method (0 )) }) // .t0.W
2972
+ bad (func () { call (v .Field (0 ).Method (1 )) }) // .t0.w
2973
+ bad (func () { call (v .Field (0 ).Elem ().Method (2 )) }) // .t0.w
2974
+ ok (func () { call (v .Field (1 ).Method (0 )) }) // .T1.Y
2975
+ ok (func () { call (v .Field (1 ).Elem ().Method (0 )) }) // .T1.Y
2976
+ bad (func () { call (v .Field (1 ).Method (1 )) }) // .T1.y
2977
+ bad (func () { call (v .Field (1 ).Elem ().Method (2 )) }) // .T1.y
2978
+
2979
+ ok (func () { call (v .Field (2 ).Method (0 )) }) // .NamedT0.W
2980
+ ok (func () { call (v .Field (2 ).Elem ().Method (0 )) }) // .NamedT0.W
2981
+ bad (func () { call (v .Field (2 ).Method (1 )) }) // .NamedT0.w
2982
+ bad (func () { call (v .Field (2 ).Elem ().Method (2 )) }) // .NamedT0.w
2983
+
2984
+ ok (func () { call (v .Field (3 ).Method (0 )) }) // .NamedT1.Y
2985
+ ok (func () { call (v .Field (3 ).Elem ().Method (0 )) }) // .NamedT1.Y
2986
+ bad (func () { call (v .Field (3 ).Method (1 )) }) // .NamedT1.y
2987
+ bad (func () { call (v .Field (3 ).Elem ().Method (3 )) }) // .NamedT1.y
2988
+
2989
+ ok (func () { call (v .Field (4 ).Field (0 ).Method (0 )) }) // .NamedT2.T1.Y
2990
+ ok (func () { call (v .Field (4 ).Field (0 ).Elem ().Method (0 )) }) // .NamedT2.T1.W
2991
+ ok (func () { call (v .Field (4 ).Field (1 ).Method (0 )) }) // .NamedT2.t0.W
2992
+ ok (func () { call (v .Field (4 ).Field (1 ).Elem ().Method (0 )) }) // .NamedT2.t0.W
2993
+
2994
+ bad (func () { call (v .Field (5 ).Method (0 )) }) // .namedT0.W
2995
+ bad (func () { call (v .Field (5 ).Elem ().Method (0 )) }) // .namedT0.W
2996
+ bad (func () { call (v .Field (5 ).Method (1 )) }) // .namedT0.w
2997
+ bad (func () { call (v .Field (5 ).Elem ().Method (2 )) }) // .namedT0.w
2998
+
2999
+ bad (func () { call (v .Field (6 ).Method (0 )) }) // .namedT1.Y
3000
+ bad (func () { call (v .Field (6 ).Elem ().Method (0 )) }) // .namedT1.Y
3001
+ bad (func () { call (v .Field (6 ).Method (0 )) }) // .namedT1.y
3002
+ bad (func () { call (v .Field (6 ).Elem ().Method (0 )) }) // .namedT1.y
3003
+
3004
+ bad (func () { call (v .Field (7 ).Field (0 ).Method (0 )) }) // .namedT2.T1.Y
3005
+ bad (func () { call (v .Field (7 ).Field (0 ).Elem ().Method (0 )) }) // .namedT2.T1.W
3006
+ bad (func () { call (v .Field (7 ).Field (1 ).Method (0 )) }) // .namedT2.t0.W
3007
+ bad (func () { call (v .Field (7 ).Field (1 ).Elem ().Method (0 )) }) // .namedT2.t0.W
3008
+ }
3009
+
2820
3010
func shouldPanic (f func ()) {
2821
3011
defer func () {
2822
3012
if recover () == nil {
0 commit comments