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") | ||||
| 	} | ||||
| } | ||||
|  |  | |||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче
	
	 Ayke van Laethem
						Ayke van Laethem