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

Method createUnsafeSliceStringCheck

compiler/asserts.go:95–122  ·  view source on GitHub ↗

createUnsafeSliceStringCheck inserts a runtime check used for unsafe.Slice and unsafe.String. This function must panic if the ptr/len parameters are invalid.

(name string, ptr, len llvm.Value, elementType llvm.Type, lenType *types.Basic)

Source from the content-addressed store, hash-verified

93// and unsafe.String. This function must panic if the ptr/len parameters are
94// invalid.
95func (b *builder) createUnsafeSliceStringCheck(name string, ptr, len llvm.Value, elementType llvm.Type, lenType *types.Basic) {
96 // From the documentation of unsafe.Slice and unsafe.String:
97 // > At run time, if len is negative, or if ptr is nil and len is not
98 // > zero, a run-time panic occurs.
99 // However, in practice, it is also necessary to check that the length is
100 // not too big that a GEP wouldn't be possible without wrapping the pointer.
101 // These two checks (non-negative and not too big) can be merged into one
102 // using an unsigned greater than.
103
104 // Make sure the len value is at least as big as a uintptr.
105 len = b.extendInteger(len, lenType, b.uintptrType)
106
107 // Determine the maximum slice size, and therefore the maximum value of the
108 // len parameter.
109 maxSize := b.maxSliceSize(elementType)
110 maxSizeValue := llvm.ConstInt(len.Type(), maxSize, false)
111
112 // Do the check. By using unsigned greater than for the length check, signed
113 // negative values are also checked (which are very large numbers when
114 // interpreted as signed values).
115 zero := llvm.ConstInt(len.Type(), 0, false)
116 lenOutOfBounds := b.CreateICmp(llvm.IntUGT, len, maxSizeValue, "")
117 ptrIsNil := b.CreateICmp(llvm.IntEQ, ptr, llvm.ConstNull(ptr.Type()), "")
118 lenIsNotZero := b.CreateICmp(llvm.IntNE, len, zero, "")
119 assert := b.CreateAnd(ptrIsNil, lenIsNotZero, "")
120 assert = b.CreateOr(assert, lenOutOfBounds, "")
121 b.createRuntimeAssert(assert, name, "unsafeSlicePanic")
122}
123
124// createChanBoundsCheck creates a bounds check before creating a new channel to
125// check that the value is not too big for runtime.chanMake.

Callers 1

createBuiltinMethod · 0.95

Calls 4

extendIntegerMethod · 0.95
createRuntimeAssertMethod · 0.95
maxSliceSizeMethod · 0.80
TypeMethod · 0.45

Tested by

no test coverage detected