createChanBoundsCheck creates a bounds check before creating a new channel to check that the value is not too big for runtime.chanMake.
(elementSize uint64, bufSize llvm.Value, bufSizeType *types.Basic, pos token.Pos)
| 124 | // createChanBoundsCheck creates a bounds check before creating a new channel to |
| 125 | // check that the value is not too big for runtime.chanMake. |
| 126 | func (b *builder) createChanBoundsCheck(elementSize uint64, bufSize llvm.Value, bufSizeType *types.Basic, pos token.Pos) { |
| 127 | if b.info.nobounds { |
| 128 | // The //go:nobounds pragma was added to the function to avoid bounds |
| 129 | // checking. |
| 130 | return |
| 131 | } |
| 132 | |
| 133 | // Make sure bufSize is at least as big as maxBufSize (an uintptr). |
| 134 | bufSize = b.extendInteger(bufSize, bufSizeType, b.uintptrType) |
| 135 | |
| 136 | // Calculate (^uintptr(0)) >> 1, which is the max value that fits in an |
| 137 | // uintptr if uintptrs were signed. |
| 138 | maxBufSize := b.CreateLShr(llvm.ConstNot(llvm.ConstInt(b.uintptrType, 0, false)), llvm.ConstInt(b.uintptrType, 1, false), "") |
| 139 | if elementSize > maxBufSize.ZExtValue() { |
| 140 | b.addError(pos, fmt.Sprintf("channel element type is too big (%v bytes)", elementSize)) |
| 141 | return |
| 142 | } |
| 143 | // Avoid divide-by-zero. |
| 144 | if elementSize == 0 { |
| 145 | elementSize = 1 |
| 146 | } |
| 147 | // Make the maxBufSize actually the maximum allowed value (in number of |
| 148 | // elements in the channel buffer). |
| 149 | maxBufSize = b.CreateUDiv(maxBufSize, llvm.ConstInt(b.uintptrType, elementSize, false), "") |
| 150 | |
| 151 | // Make sure maxBufSize has the same type as bufSize. |
| 152 | if maxBufSize.Type() != bufSize.Type() { |
| 153 | maxBufSize = b.CreateZExt(maxBufSize, bufSize.Type(), "") |
| 154 | } |
| 155 | |
| 156 | // Do the check for a too large (or negative) buffer size. |
| 157 | bufSizeTooBig := b.CreateICmp(llvm.IntUGE, bufSize, maxBufSize, "") |
| 158 | b.createRuntimeAssert(bufSizeTooBig, "chan", "chanMakePanic") |
| 159 | } |
| 160 | |
| 161 | // createNilCheck checks whether the given pointer is nil, and panics if it is. |
| 162 | // It has no effect in well-behaved programs, but makes sure no uncaught nil |
no test coverage detected