@@ -681,6 +681,39 @@ func TestDeletePanics(t *testing.T) {
681
681
}
682
682
}
683
683
684
+ func TestDeleteClearTail (t * testing.T ) {
685
+ mem := []* int {new (int ), new (int ), new (int ), new (int ), new (int ), new (int )}
686
+ s := mem [0 :5 ] // there is 1 element beyond len(s), within cap(s)
687
+
688
+ s = Delete (s , 2 , 4 )
689
+
690
+ if mem [3 ] != nil || mem [4 ] != nil {
691
+ // Check that potential memory leak is avoided
692
+ t .Errorf ("Delete: want nil discarded elements, got %v, %v" , mem [3 ], mem [4 ])
693
+ }
694
+ if mem [5 ] == nil {
695
+ t .Errorf ("Delete: want unchanged elements beyond original len, got nil" )
696
+ }
697
+ }
698
+
699
+ func TestDeleteFuncClearTail (t * testing.T ) {
700
+ mem := []* int {new (int ), new (int ), new (int ), new (int ), new (int ), new (int )}
701
+ * mem [2 ], * mem [3 ] = 42 , 42
702
+ s := mem [0 :5 ] // there is 1 element beyond len(s), within cap(s)
703
+
704
+ s = DeleteFunc (s , func (i * int ) bool {
705
+ return i != nil && * i == 42
706
+ })
707
+
708
+ if mem [3 ] != nil || mem [4 ] != nil {
709
+ // Check that potential memory leak is avoided
710
+ t .Errorf ("DeleteFunc: want nil discarded elements, got %v, %v" , mem [3 ], mem [4 ])
711
+ }
712
+ if mem [5 ] == nil {
713
+ t .Errorf ("DeleteFunc: want unchanged elements beyond original len, got nil" )
714
+ }
715
+ }
716
+
684
717
func TestClone (t * testing.T ) {
685
718
s1 := []int {1 , 2 , 3 }
686
719
s2 := Clone (s1 )
@@ -784,6 +817,53 @@ func TestCompactFunc(t *testing.T) {
784
817
}
785
818
}
786
819
820
+ func TestCompactClearTail (t * testing.T ) {
821
+ one , two , three , four := 1 , 2 , 3 , 4
822
+ mem := []* int {& one , & one , & two , & two , & three , & four }
823
+ s := mem [0 :5 ] // there is 1 element beyond len(s), within cap(s)
824
+ copy := Clone (s )
825
+
826
+ s = Compact (s )
827
+
828
+ if want := []* int {& one , & two , & three }; ! Equal (s , want ) {
829
+ t .Errorf ("Compact(%v) = %v, want %v" , copy , s , want )
830
+ }
831
+
832
+ if mem [3 ] != nil || mem [4 ] != nil {
833
+ // Check that potential memory leak is avoided
834
+ t .Errorf ("Compact: want nil discarded elements, got %v, %v" , mem [3 ], mem [4 ])
835
+ }
836
+ if mem [5 ] != & four {
837
+ t .Errorf ("Compact: want unchanged element beyond original len, got %v" , mem [5 ])
838
+ }
839
+ }
840
+
841
+ func TestCompactFuncClearTail (t * testing.T ) {
842
+ a , b , c , d , e , f := 1 , 1 , 2 , 2 , 3 , 4
843
+ mem := []* int {& a , & b , & c , & d , & e , & f }
844
+ s := mem [0 :5 ] // there is 1 element beyond len(s), within cap(s)
845
+ copy := Clone (s )
846
+
847
+ s = CompactFunc (s , func (x , y * int ) bool {
848
+ if x == nil || y == nil {
849
+ return x == y
850
+ }
851
+ return * x == * y
852
+ })
853
+
854
+ if want := []* int {& a , & c , & e }; ! Equal (s , want ) {
855
+ t .Errorf ("CompactFunc(%v) = %v, want %v" , copy , s , want )
856
+ }
857
+
858
+ if mem [3 ] != nil || mem [4 ] != nil {
859
+ // Check that potential memory leak is avoided
860
+ t .Errorf ("CompactFunc: want nil discarded elements, got %v, %v" , mem [3 ], mem [4 ])
861
+ }
862
+ if mem [5 ] != & f {
863
+ t .Errorf ("CompactFunc: want unchanged elements beyond original len, got %v" , mem [5 ])
864
+ }
865
+ }
866
+
787
867
func BenchmarkCompactFunc_Large (b * testing.B ) {
788
868
type Large [4 * 1024 ]byte
789
869
@@ -954,6 +1034,56 @@ func TestReplacePanics(t *testing.T) {
954
1034
}
955
1035
}
956
1036
1037
+ func TestReplaceGrow (t * testing.T ) {
1038
+ // When Replace needs to allocate a new slice, we want the original slice
1039
+ // to not be changed.
1040
+ a , b , c , d , e , f := 1 , 2 , 3 , 4 , 5 , 6
1041
+ mem := []* int {& a , & b , & c , & d , & e , & f }
1042
+ memcopy := Clone (mem )
1043
+ s := mem [0 :5 ] // there is 1 element beyond len(s), within cap(s)
1044
+ copy := Clone (s )
1045
+ original := s
1046
+
1047
+ // The new elements don't fit within cap(s), so Replace will allocate.
1048
+ z := 99
1049
+ s = Replace (s , 1 , 3 , & z , & z , & z , & z )
1050
+
1051
+ if want := []* int {& a , & z , & z , & z , & z , & d , & e }; ! Equal (s , want ) {
1052
+ t .Errorf ("Replace(%v, 1, 3, %v, %v, %v, %v) = %v, want %v" , copy , & z , & z , & z , & z , s , want )
1053
+ }
1054
+
1055
+ if ! Equal (original , copy ) {
1056
+ t .Errorf ("original slice has changed, got %v, want %v" , original , copy )
1057
+ }
1058
+
1059
+ if ! Equal (mem , memcopy ) {
1060
+ // Changing the original tail s[len(s):cap(s)] is unwanted
1061
+ t .Errorf ("original backing memory has changed, got %v, want %v" , mem , memcopy )
1062
+ }
1063
+ }
1064
+
1065
+ func TestReplaceClearTail (t * testing.T ) {
1066
+ a , b , c , d , e , f := 1 , 2 , 3 , 4 , 5 , 6
1067
+ mem := []* int {& a , & b , & c , & d , & e , & f }
1068
+ s := mem [0 :5 ] // there is 1 element beyond len(s), within cap(s)
1069
+ copy := Clone (s )
1070
+
1071
+ y , z := 8 , 9
1072
+ s = Replace (s , 1 , 4 , & y , & z )
1073
+
1074
+ if want := []* int {& a , & y , & z , & e }; ! Equal (s , want ) {
1075
+ t .Errorf ("Replace(%v) = %v, want %v" , copy , s , want )
1076
+ }
1077
+
1078
+ if mem [4 ] != nil {
1079
+ // Check that potential memory leak is avoided
1080
+ t .Errorf ("Replace: want nil discarded element, got %v" , mem [4 ])
1081
+ }
1082
+ if mem [5 ] != & f {
1083
+ t .Errorf ("Replace: want unchanged elements beyond original len, got %v" , mem [5 ])
1084
+ }
1085
+ }
1086
+
957
1087
func TestReplaceOverlap (t * testing.T ) {
958
1088
const N = 10
959
1089
a := make ([]int , N )
0 commit comments