Browse Source

interp: return a proper error message when indexing out of range

This helps debug issues inside interp.
fix-docker-llvm-build
Ayke van Laethem 8 months ago
committed by Ron Evans
parent
commit
9951eb9990
  1. 22
      interp/interpreter.go
  2. 6
      interp/memory.go

22
interp/interpreter.go

@ -427,7 +427,11 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
if err != nil { if err != nil {
return nil, mem, r.errorAt(inst, err) return nil, mem, r.errorAt(inst, err)
} }
methodSetPtr, err := mem.load(typecodePtr.addOffset(-int64(r.pointerSize)), r.pointerSize).asPointer(r) typecodePtrOffset, err := typecodePtr.addOffset(-int64(r.pointerSize))
if err != nil {
return nil, mem, r.errorAt(inst, err) // unlikely
}
methodSetPtr, err := mem.load(typecodePtrOffset, r.pointerSize).asPointer(r)
if err != nil { if err != nil {
return nil, mem, r.errorAt(inst, err) return nil, mem, r.errorAt(inst, err)
} }
@ -473,7 +477,11 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
if err != nil { if err != nil {
return nil, mem, r.errorAt(inst, err) return nil, mem, r.errorAt(inst, err)
} }
methodSetPtr, err := mem.load(typecodePtr.addOffset(-int64(r.pointerSize)), r.pointerSize).asPointer(r) typecodePtrOffset, err := typecodePtr.addOffset(-int64(r.pointerSize))
if err != nil {
return nil, mem, r.errorAt(inst, err)
}
methodSetPtr, err := mem.load(typecodePtrOffset, r.pointerSize).asPointer(r)
if err != nil { if err != nil {
return nil, mem, r.errorAt(inst, err) return nil, mem, r.errorAt(inst, err)
} }
@ -658,7 +666,10 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
locals[inst.localIndex] = makeLiteralInt(ptrValue, int(operands[0].len(r)*8)) locals[inst.localIndex] = makeLiteralInt(ptrValue, int(operands[0].len(r)*8))
continue continue
} }
ptr = ptr.addOffset(int64(offset)) ptr, err = ptr.addOffset(int64(offset))
if err != nil {
return nil, mem, r.errorAt(inst, err)
}
locals[inst.localIndex] = ptr locals[inst.localIndex] = ptr
if r.debug { if r.debug {
fmt.Fprintln(os.Stderr, indent+"gep:", operands, "->", ptr) fmt.Fprintln(os.Stderr, indent+"gep:", operands, "->", ptr)
@ -756,7 +767,10 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
if inst.opcode == llvm.Add { if inst.opcode == llvm.Add {
// This likely means this is part of a // This likely means this is part of a
// unsafe.Pointer(uintptr(ptr) + offset) pattern. // unsafe.Pointer(uintptr(ptr) + offset) pattern.
lhsPtr = lhsPtr.addOffset(int64(rhs.Uint())) lhsPtr, err = lhsPtr.addOffset(int64(rhs.Uint()))
if err != nil {
return nil, mem, r.errorAt(inst, err)
}
locals[inst.localIndex] = lhsPtr locals[inst.localIndex] = lhsPtr
} else if inst.opcode == llvm.Xor && rhs.Uint() == 0 { } else if inst.opcode == llvm.Xor && rhs.Uint() == 0 {
// Special workaround for strings.noescape, see // Special workaround for strings.noescape, see

6
interp/memory.go

@ -517,12 +517,12 @@ func (v pointerValue) offset() uint32 {
// addOffset essentially does a GEP operation (pointer arithmetic): it adds the // addOffset essentially does a GEP operation (pointer arithmetic): it adds the
// offset to the pointer. It also checks that the offset doesn't overflow the // offset to the pointer. It also checks that the offset doesn't overflow the
// maximum offset size (which is 4GB). // maximum offset size (which is 4GB).
func (v pointerValue) addOffset(offset int64) pointerValue { func (v pointerValue) addOffset(offset int64) (pointerValue, error) {
result := pointerValue{v.pointer + uint64(offset)} result := pointerValue{v.pointer + uint64(offset)}
if checks && v.index() != result.index() { if checks && v.index() != result.index() {
panic("interp: offset out of range") return result, fmt.Errorf("interp: offset %d out of range for object %v", offset, v)
} }
return result return result, nil
} }
func (v pointerValue) len(r *runner) uint32 { func (v pointerValue) len(r *runner) uint32 {

Loading…
Cancel
Save