compiler: fix make([]T, ...) with big integers on 32-bit systems or less
Previously, this would have resulted in a LLVM verification error because runtime.sliceBoundsCheckMake would not accept 64-bit integers on these platforms.
Этот коммит содержится в:
родитель
28987ae061
коммит
8e99c3313b
2 изменённых файлов: 24 добавлений и 7 удалений
|
@ -1730,21 +1730,31 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
|||
|
||||
// Bounds checking.
|
||||
if !frame.fn.IsNoBounds() {
|
||||
if sliceLen.Type().IntTypeWidth() < c.uintptrType.IntTypeWidth() {
|
||||
checkFunc := "sliceBoundsCheckMake"
|
||||
biggestInt := c.uintptrType
|
||||
biggestIntWidth := biggestInt.IntTypeWidth()
|
||||
if sliceLen.Type().IntTypeWidth() > biggestIntWidth || sliceCap.Type().IntTypeWidth() > biggestIntWidth {
|
||||
// System that is less than 64bit, meaning that the slice make
|
||||
// params are bigger than uintptr.
|
||||
checkFunc = "sliceBoundsCheckMake64"
|
||||
biggestInt = c.ctx.Int64Type()
|
||||
biggestIntWidth = biggestInt.IntTypeWidth()
|
||||
}
|
||||
if sliceLen.Type().IntTypeWidth() < biggestIntWidth {
|
||||
if expr.Len.Type().(*types.Basic).Info()&types.IsUnsigned != 0 {
|
||||
sliceLen = c.builder.CreateZExt(sliceLen, c.uintptrType, "")
|
||||
sliceLen = c.builder.CreateZExt(sliceLen, biggestInt, "")
|
||||
} else {
|
||||
sliceLen = c.builder.CreateSExt(sliceLen, c.uintptrType, "")
|
||||
sliceLen = c.builder.CreateSExt(sliceLen, biggestInt, "")
|
||||
}
|
||||
}
|
||||
if sliceCap.Type().IntTypeWidth() < c.uintptrType.IntTypeWidth() {
|
||||
if sliceCap.Type().IntTypeWidth() < biggestIntWidth {
|
||||
if expr.Cap.Type().(*types.Basic).Info()&types.IsUnsigned != 0 {
|
||||
sliceCap = c.builder.CreateZExt(sliceCap, c.uintptrType, "")
|
||||
sliceCap = c.builder.CreateZExt(sliceCap, biggestInt, "")
|
||||
} else {
|
||||
sliceCap = c.builder.CreateSExt(sliceCap, c.uintptrType, "")
|
||||
sliceCap = c.builder.CreateSExt(sliceCap, biggestInt, "")
|
||||
}
|
||||
}
|
||||
c.createRuntimeCall("sliceBoundsCheckMake", []llvm.Value{sliceLen, sliceCap}, "")
|
||||
c.createRuntimeCall(checkFunc, []llvm.Value{sliceLen, sliceCap}, "")
|
||||
}
|
||||
|
||||
// Allocate the backing array.
|
||||
|
|
|
@ -62,3 +62,10 @@ func sliceBoundsCheckMake(length, capacity uint) {
|
|||
runtimePanic("slice size out of range")
|
||||
}
|
||||
}
|
||||
|
||||
// Check for bounds in *ssa.MakeSlice. Supports 64-bit indexes.
|
||||
func sliceBoundsCheckMake64(length, capacity uint64) {
|
||||
if !(0 <= length && length <= capacity) {
|
||||
runtimePanic("slice size out of range")
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче