@@ -38,6 +38,8 @@ const (
3838 upperBounded
3939)
4040
41+ const maxDepth = 20
42+
4143func newSliceBoundsAnalyzer (id string , description string ) * analysis.Analyzer {
4244 return & analysis.Analyzer {
4345 Name : id ,
@@ -75,7 +77,7 @@ func runSliceBounds(pass *analysis.Pass) (interface{}, error) {
7577 l , h := extractSliceBounds (slice )
7678 newCap := computeSliceNewCap (l , h , sliceCap )
7779 violations := []ssa.Instruction {}
78- trackSliceBounds (newCap , slice , & violations , ifs )
80+ trackSliceBounds (0 , newCap , slice , & violations , ifs )
7981 for _ , s := range violations {
8082 switch s := s .(type ) {
8183 case * ssa.Slice :
@@ -155,7 +157,11 @@ func runSliceBounds(pass *analysis.Pass) (interface{}, error) {
155157 return nil , nil
156158}
157159
158- func trackSliceBounds (sliceCap int , slice ssa.Node , violations * []ssa.Instruction , ifs map [ssa.If ]* ssa.BinOp ) {
160+ func trackSliceBounds (depth int , sliceCap int , slice ssa.Node , violations * []ssa.Instruction , ifs map [ssa.If ]* ssa.BinOp ) {
161+ if depth == maxDepth {
162+ return
163+ }
164+ depth ++
159165 if violations == nil {
160166 violations = & []ssa.Instruction {}
161167 }
@@ -164,12 +170,12 @@ func trackSliceBounds(sliceCap int, slice ssa.Node, violations *[]ssa.Instructio
164170 for _ , refinstr := range * referrers {
165171 switch refinstr := refinstr .(type ) {
166172 case * ssa.Slice :
167- checkAllSlicesBounds (sliceCap , refinstr , violations , ifs )
173+ checkAllSlicesBounds (depth , sliceCap , refinstr , violations , ifs )
168174 switch refinstr .X .(type ) {
169175 case * ssa.Alloc , * ssa.Parameter :
170176 l , h := extractSliceBounds (refinstr )
171177 newCap := computeSliceNewCap (l , h , sliceCap )
172- trackSliceBounds (newCap , refinstr , violations , ifs )
178+ trackSliceBounds (depth , newCap , refinstr , violations , ifs )
173179 }
174180 case * ssa.IndexAddr :
175181 indexValue , err := extractIntValue (refinstr .Index .String ())
@@ -189,7 +195,7 @@ func trackSliceBounds(sliceCap int, slice ssa.Node, violations *[]ssa.Instructio
189195 if fn , ok := refinstr .Call .Value .(* ssa.Function ); ok {
190196 if len (fn .Params ) > parPos && parPos > - 1 {
191197 param := fn .Params [parPos ]
192- trackSliceBounds (sliceCap , param , violations , ifs )
198+ trackSliceBounds (depth , sliceCap , param , violations , ifs )
193199 }
194200 }
195201 }
@@ -198,7 +204,11 @@ func trackSliceBounds(sliceCap int, slice ssa.Node, violations *[]ssa.Instructio
198204 }
199205}
200206
201- func checkAllSlicesBounds (sliceCap int , slice * ssa.Slice , violations * []ssa.Instruction , ifs map [ssa.If ]* ssa.BinOp ) {
207+ func checkAllSlicesBounds (depth int , sliceCap int , slice * ssa.Slice , violations * []ssa.Instruction , ifs map [ssa.If ]* ssa.BinOp ) {
208+ if depth == maxDepth {
209+ return
210+ }
211+ depth ++
202212 if violations == nil {
203213 violations = & []ssa.Instruction {}
204214 }
@@ -210,7 +220,7 @@ func checkAllSlicesBounds(sliceCap int, slice *ssa.Slice, violations *[]ssa.Inst
210220 case * ssa.Alloc , * ssa.Parameter , * ssa.Slice :
211221 l , h := extractSliceBounds (slice )
212222 newCap := computeSliceNewCap (l , h , sliceCap )
213- trackSliceBounds (newCap , slice , violations , ifs )
223+ trackSliceBounds (depth , newCap , slice , violations , ifs )
214224 }
215225
216226 references := slice .Referrers ()
@@ -220,12 +230,12 @@ func checkAllSlicesBounds(sliceCap int, slice *ssa.Slice, violations *[]ssa.Inst
220230 for _ , ref := range * references {
221231 switch s := ref .(type ) {
222232 case * ssa.Slice :
223- checkAllSlicesBounds (sliceCap , s , violations , ifs )
233+ checkAllSlicesBounds (depth , sliceCap , s , violations , ifs )
224234 switch s .X .(type ) {
225235 case * ssa.Alloc , * ssa.Parameter :
226236 l , h := extractSliceBounds (s )
227237 newCap := computeSliceNewCap (l , h , sliceCap )
228- trackSliceBounds (newCap , s , violations , ifs )
238+ trackSliceBounds (depth , newCap , s , violations , ifs )
229239 }
230240 }
231241 }
0 commit comments