diff --git a/compiler/compiler.go b/compiler/compiler.go index e729ca1e7..397cb6614 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -1324,7 +1324,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { llvm.ConstInt(c.ctx.Int32Type(), 0, false), llvm.ConstInt(c.ctx.Int32Type(), uint64(expr.Field), false), } - return c.builder.CreateGEP(val, indices, ""), nil + return c.builder.CreateInBoundsGEP(val, indices, ""), nil } case *ssa.Function: panic("function is not an expression") @@ -1344,7 +1344,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { alloca := c.builder.CreateAlloca(array.Type(), "index.alloca") c.builder.CreateStore(array, alloca) zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false) - ptr := c.builder.CreateGEP(alloca, []llvm.Value{zero, index}, "index.gep") + ptr := c.builder.CreateInBoundsGEP(alloca, []llvm.Value{zero, index}, "index.gep") return c.builder.CreateLoad(ptr, "index.load"), nil case *ssa.IndexAddr: val := c.getValue(frame, expr.X) @@ -1385,9 +1385,9 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { llvm.ConstInt(c.ctx.Int32Type(), 0, false), index, } - return c.builder.CreateGEP(bufptr, indices, ""), nil + return c.builder.CreateInBoundsGEP(bufptr, indices, ""), nil case *types.Slice: - return c.builder.CreateGEP(bufptr, []llvm.Value{index}, ""), nil + return c.builder.CreateInBoundsGEP(bufptr, []llvm.Value{index}, ""), nil default: panic("unreachable") } @@ -1407,7 +1407,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { // Lookup byte buf := c.builder.CreateExtractValue(value, 0, "") - bufPtr := c.builder.CreateGEP(buf, []llvm.Value{index}, "") + bufPtr := c.builder.CreateInBoundsGEP(buf, []llvm.Value{index}, "") return c.builder.CreateLoad(bufPtr, ""), nil case *types.Map: valueType := expr.Type() @@ -1608,7 +1608,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { } sliceLen := c.builder.CreateSub(high, low, "slice.len") - slicePtr := c.builder.CreateGEP(value, indices, "slice.ptr") + slicePtr := c.builder.CreateInBoundsGEP(value, indices, "slice.ptr") sliceCap := c.builder.CreateSub(llvmLen, low, "slice.cap") slice := c.ctx.ConstStruct([]llvm.Value{ @@ -1641,7 +1641,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { high = c.builder.CreateTrunc(high, c.uintptrType, "") } - newPtr := c.builder.CreateGEP(oldPtr, []llvm.Value{low}, "") + newPtr := c.builder.CreateInBoundsGEP(oldPtr, []llvm.Value{low}, "") newLen := c.builder.CreateSub(high, low, "") newCap := c.builder.CreateSub(oldCap, low, "") slice := c.ctx.ConstStruct([]llvm.Value{ @@ -1676,7 +1676,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { high = c.builder.CreateTrunc(high, c.uintptrType, "") } - newPtr := c.builder.CreateGEP(oldPtr, []llvm.Value{low}, "") + newPtr := c.builder.CreateInBoundsGEP(oldPtr, []llvm.Value{low}, "") newLen := c.builder.CreateSub(high, low, "") str := llvm.Undef(c.mod.GetTypeByName("runtime._string")) str = c.builder.CreateInsertValue(str, newPtr, 0, "") @@ -2119,7 +2119,11 @@ func (c *Compiler) parseConvert(typeFrom, typeTo types.Type, value llvm.Value, p // This pointer can be calculated from the original // ptrtoint instruction with a GEP. The leftover inttoptr // instruction is trivial to optimize away. - return c.builder.CreateGEP(origptr, []llvm.Value{index}, ""), nil + // Making it an in bounds GEP even though it's easy to + // create a GEP that is not in bounds. However, we're + // talking about unsafe code here so the programmer has to + // be careful anyway. + return c.builder.CreateInBoundsGEP(origptr, []llvm.Value{index}, ""), nil } } } diff --git a/compiler/defer.go b/compiler/defer.go index 016c1c73f..1246f03a0 100644 --- a/compiler/defer.go +++ b/compiler/defer.go @@ -172,13 +172,13 @@ func (c *Compiler) emitRunDefers(frame *Frame) { // stack = stack.next // switch stack.callback { c.builder.SetInsertPointAtEnd(loop) - nextStackGEP := c.builder.CreateGEP(deferData, []llvm.Value{ + nextStackGEP := c.builder.CreateInBoundsGEP(deferData, []llvm.Value{ llvm.ConstInt(c.ctx.Int32Type(), 0, false), llvm.ConstInt(c.ctx.Int32Type(), 1, false), // .next field }, "stack.next.gep") nextStack := c.builder.CreateLoad(nextStackGEP, "stack.next") c.builder.CreateStore(nextStack, frame.deferPtr) - gep := c.builder.CreateGEP(deferData, []llvm.Value{ + gep := c.builder.CreateInBoundsGEP(deferData, []llvm.Value{ llvm.ConstInt(c.ctx.Int32Type(), 0, false), llvm.ConstInt(c.ctx.Int32Type(), 0, false), // .callback field }, "callback.gep") @@ -211,7 +211,7 @@ func (c *Compiler) emitRunDefers(frame *Frame) { forwardParams := []llvm.Value{} zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false) for i := 2; i < len(valueTypes); i++ { - gep := c.builder.CreateGEP(deferFramePtr, []llvm.Value{zero, llvm.ConstInt(c.ctx.Int32Type(), uint64(i), false)}, "gep") + gep := c.builder.CreateInBoundsGEP(deferFramePtr, []llvm.Value{zero, llvm.ConstInt(c.ctx.Int32Type(), uint64(i), false)}, "gep") forwardParam := c.builder.CreateLoad(gep, "param") forwardParams = append(forwardParams, forwardParam) } @@ -242,7 +242,7 @@ func (c *Compiler) emitRunDefers(frame *Frame) { forwardParams := []llvm.Value{} zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false) for i := range callback.Params { - gep := c.builder.CreateGEP(deferFramePtr, []llvm.Value{zero, llvm.ConstInt(c.ctx.Int32Type(), uint64(i+2), false)}, "gep") + gep := c.builder.CreateInBoundsGEP(deferFramePtr, []llvm.Value{zero, llvm.ConstInt(c.ctx.Int32Type(), uint64(i+2), false)}, "gep") forwardParam := c.builder.CreateLoad(gep, "param") forwardParams = append(forwardParams, forwardParam) } @@ -273,7 +273,7 @@ func (c *Compiler) emitRunDefers(frame *Frame) { forwardParams := []llvm.Value{} zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false) for i := 2; i < len(valueTypes); i++ { - gep := c.builder.CreateGEP(deferFramePtr, []llvm.Value{zero, llvm.ConstInt(c.ctx.Int32Type(), uint64(i), false)}, "") + gep := c.builder.CreateInBoundsGEP(deferFramePtr, []llvm.Value{zero, llvm.ConstInt(c.ctx.Int32Type(), uint64(i), false)}, "") forwardParam := c.builder.CreateLoad(gep, "param") forwardParams = append(forwardParams, forwardParam) } diff --git a/compiler/goroutine-lowering.go b/compiler/goroutine-lowering.go index fa4983444..aae344d85 100644 --- a/compiler/goroutine-lowering.go +++ b/compiler/goroutine-lowering.go @@ -485,7 +485,7 @@ func (c *Compiler) markAsyncFunctions() (needsScheduler bool, err error) { llvm.ConstInt(c.ctx.Int1Type(), 0, false), }, "task.promise.raw") promise := c.builder.CreateBitCast(promiseRaw, llvm.PointerType(promiseType, 0), "task.promise") - dataPtr := c.builder.CreateGEP(promise, []llvm.Value{ + dataPtr := c.builder.CreateInBoundsGEP(promise, []llvm.Value{ llvm.ConstInt(c.ctx.Int32Type(), 0, false), llvm.ConstInt(c.ctx.Int32Type(), 2, false), }, "task.promise.data") @@ -546,13 +546,13 @@ func (c *Compiler) markAsyncFunctions() (needsScheduler bool, err error) { llvm.ConstInt(c.ctx.Int1Type(), 0, false), }, "task.promise.raw") promise := c.builder.CreateBitCast(promiseRaw, llvm.PointerType(promiseType, 0), "task.promise") - dataPtr := c.builder.CreateGEP(promise, []llvm.Value{ + dataPtr := c.builder.CreateInBoundsGEP(promise, []llvm.Value{ llvm.ConstInt(c.ctx.Int32Type(), 0, false), llvm.ConstInt(c.ctx.Int32Type(), 2, false), }, "task.promise.data") valueAlloca.ReplaceAllUsesWith(c.builder.CreateBitCast(dataPtr, valueAlloca.Type(), "")) valueAlloca.EraseFromParentAsInstruction() - commaOkPtr := c.builder.CreateGEP(promise, []llvm.Value{ + commaOkPtr := c.builder.CreateInBoundsGEP(promise, []llvm.Value{ llvm.ConstInt(c.ctx.Int32Type(), 0, false), llvm.ConstInt(c.ctx.Int32Type(), 1, false), }, "task.promise.comma-ok")