compiler: truncate string slice indices if necessary
This didn't trigger on most platforms but does trigger on AVR where almost all slice operations on strings are with integers that are bigger than uintptr.
Этот коммит содержится в:
родитель
30e192e7e8
коммит
81a1114ee5
1 изменённых файлов: 13 добавлений и 0 удалений
|
@ -1973,6 +1973,8 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
||||||
|
|
||||||
c.emitSliceBoundsCheck(frame, llvmLen, low, high, lowType, highType)
|
c.emitSliceBoundsCheck(frame, llvmLen, low, high, lowType, highType)
|
||||||
|
|
||||||
|
// Truncate ints bigger than uintptr. This is after the bounds
|
||||||
|
// check so it's safe.
|
||||||
if c.targetData.TypeAllocSize(high.Type()) > c.targetData.TypeAllocSize(c.uintptrType) {
|
if c.targetData.TypeAllocSize(high.Type()) > c.targetData.TypeAllocSize(c.uintptrType) {
|
||||||
high = c.builder.CreateTrunc(high, c.uintptrType, "")
|
high = c.builder.CreateTrunc(high, c.uintptrType, "")
|
||||||
}
|
}
|
||||||
|
@ -2005,6 +2007,8 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
||||||
|
|
||||||
c.emitSliceBoundsCheck(frame, oldCap, low, high, lowType, highType)
|
c.emitSliceBoundsCheck(frame, oldCap, low, high, lowType, highType)
|
||||||
|
|
||||||
|
// Truncate ints bigger than uintptr. This is after the bounds
|
||||||
|
// check so it's safe.
|
||||||
if c.targetData.TypeAllocSize(low.Type()) > c.targetData.TypeAllocSize(c.uintptrType) {
|
if c.targetData.TypeAllocSize(low.Type()) > c.targetData.TypeAllocSize(c.uintptrType) {
|
||||||
low = c.builder.CreateTrunc(low, c.uintptrType, "")
|
low = c.builder.CreateTrunc(low, c.uintptrType, "")
|
||||||
}
|
}
|
||||||
|
@ -2038,6 +2042,15 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
||||||
|
|
||||||
c.emitSliceBoundsCheck(frame, oldLen, low, high, lowType, highType)
|
c.emitSliceBoundsCheck(frame, oldLen, low, high, lowType, highType)
|
||||||
|
|
||||||
|
// Truncate ints bigger than uintptr. This is after the bounds
|
||||||
|
// check so it's safe.
|
||||||
|
if c.targetData.TypeAllocSize(low.Type()) > c.targetData.TypeAllocSize(c.uintptrType) {
|
||||||
|
low = c.builder.CreateTrunc(low, c.uintptrType, "")
|
||||||
|
}
|
||||||
|
if c.targetData.TypeAllocSize(high.Type()) > c.targetData.TypeAllocSize(c.uintptrType) {
|
||||||
|
high = c.builder.CreateTrunc(high, c.uintptrType, "")
|
||||||
|
}
|
||||||
|
|
||||||
newPtr := c.builder.CreateGEP(oldPtr, []llvm.Value{low}, "")
|
newPtr := c.builder.CreateGEP(oldPtr, []llvm.Value{low}, "")
|
||||||
newLen := c.builder.CreateSub(high, low, "")
|
newLen := c.builder.CreateSub(high, low, "")
|
||||||
str, err := c.getZeroValue(c.mod.GetTypeByName("runtime._string"))
|
str, err := c.getZeroValue(c.mod.GetTypeByName("runtime._string"))
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче