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.
|
// Bounds checking.
|
||||||
if !frame.fn.IsNoBounds() {
|
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 {
|
if expr.Len.Type().(*types.Basic).Info()&types.IsUnsigned != 0 {
|
||||||
sliceLen = c.builder.CreateZExt(sliceLen, c.uintptrType, "")
|
sliceLen = c.builder.CreateZExt(sliceLen, biggestInt, "")
|
||||||
} else {
|
} 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 {
|
if expr.Cap.Type().(*types.Basic).Info()&types.IsUnsigned != 0 {
|
||||||
sliceCap = c.builder.CreateZExt(sliceCap, c.uintptrType, "")
|
sliceCap = c.builder.CreateZExt(sliceCap, biggestInt, "")
|
||||||
} else {
|
} 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.
|
// Allocate the backing array.
|
||||||
|
|
|
@ -62,3 +62,10 @@ func sliceBoundsCheckMake(length, capacity uint) {
|
||||||
runtimePanic("slice size out of range")
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче