compiler: make sure make([]T, ...) checks for Ts bigger than 1

Without this, the following code would not panic:

    func getInt(i int) { return i }
    make([][1<<18], getInt(1<<18))

Or this code would be allowed to compile for 32-bit systems:

    make([][1<<18], 1<<18)
This commit is contained in:
Ayke van Laethem
2019-01-27 14:27:08 +01:00
committed by Ron Evans
parent 8e99c3313b
commit 26e7e93478
2 changed files with 32 additions and 8 deletions
+10 -4
View File
@@ -57,15 +57,21 @@ func sliceBoundsCheck64(capacity uintptr, low, high uint64) {
}
// Check for bounds in *ssa.MakeSlice.
func sliceBoundsCheckMake(length, capacity uint) {
if !(0 <= length && length <= capacity) {
func sliceBoundsCheckMake(length, capacity uintptr, elementSizeDoubled uintptr) {
overflow := uint64(capacity*elementSizeDoubled) != uint64(capacity)*uint64(elementSizeDoubled)
if length > capacity || overflow {
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) {
func sliceBoundsCheckMake64(length, capacity uint64, elementSizeDoubled uintptr) {
// This function is only ever called on systems where uintptr is smaller
// than uint64 (thus must be 32-bit or less). So multiplying as uint64 will
// never overflow if we know that capacity fits in uintptr.
// That elementSizeDoubled fits in uintptr is checked by the compiler.
overflow := capacity != uint64(uintptr(capacity)) || capacity != uint64(uintptr(capacity*uint64(elementSizeDoubled)))
if length > capacity || overflow {
runtimePanic("slice size out of range")
}
}