Browse Source

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.
pull/218/head
Ayke van Laethem 6 years ago
committed by Ron Evans
parent
commit
8e99c3313b
  1. 24
      compiler/compiler.go
  2. 7
      src/runtime/panic.go

24
compiler/compiler.go

@ -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.

7
src/runtime/panic.go

@ -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")
}
}

Loading…
Cancel
Save