MCPcopy
hub / github.com/tinygo-org/tinygo / createSliceBoundsCheck

Method createSliceBoundsCheck

compiler/asserts.go:44–78  ·  view source on GitHub ↗

createSliceBoundsCheck emits a bounds check before a slicing operation to make sure it is within bounds. This function is both used for slicing a slice (low and high have their normal meaning) and for creating a new slice, where 'capacity' means the biggest possible slice capacity, 'low' means len

(capacity, low, high, max llvm.Value, lowType, highType, maxType *types.Basic)

Source from the content-addressed store, hash-verified

42// biggest possible slice capacity, 'low' means len and 'high' means cap. The
43// logic is the same in both cases.
44func (b *builder) createSliceBoundsCheck(capacity, low, high, max llvm.Value, lowType, highType, maxType *types.Basic) {
45 if b.info.nobounds {
46 // The //go:nobounds pragma was added to the function to avoid bounds
47 // checking.
48 return
49 }
50
51 // Extend the capacity integer to be at least as wide as low and high.
52 capacityType := capacity.Type()
53 if low.Type().IntTypeWidth() > capacityType.IntTypeWidth() {
54 capacityType = low.Type()
55 }
56 if high.Type().IntTypeWidth() > capacityType.IntTypeWidth() {
57 capacityType = high.Type()
58 }
59 if max.Type().IntTypeWidth() > capacityType.IntTypeWidth() {
60 capacityType = max.Type()
61 }
62 if capacityType != capacity.Type() {
63 capacity = b.CreateZExt(capacity, capacityType, "")
64 }
65
66 // Extend low and high to be the same size as capacity.
67 low = b.extendInteger(low, lowType, capacityType)
68 high = b.extendInteger(high, highType, capacityType)
69 max = b.extendInteger(max, maxType, capacityType)
70
71 // Now do the bounds check: low > high || high > capacity
72 outOfBounds1 := b.CreateICmp(llvm.IntUGT, low, high, "slice.lowhigh")
73 outOfBounds2 := b.CreateICmp(llvm.IntUGT, high, max, "slice.highmax")
74 outOfBounds3 := b.CreateICmp(llvm.IntUGT, max, capacity, "slice.maxcap")
75 outOfBounds := b.CreateOr(outOfBounds1, outOfBounds2, "slice.lowmax")
76 outOfBounds = b.CreateOr(outOfBounds, outOfBounds3, "slice.lowcap")
77 b.createRuntimeAssert(outOfBounds, "slice", "slicePanic")
78}
79
80// createSliceToArrayPointerCheck adds a check for slice-to-array pointer
81// conversions. This conversion was added in Go 1.17. For details, see:

Callers 1

createExprMethod · 0.95

Calls 3

extendIntegerMethod · 0.95
createRuntimeAssertMethod · 0.95
TypeMethod · 0.45

Tested by

no test coverage detected