Skip to content

Commit 9951eb9

Browse files
aykevldeadprogram
authored andcommitted
interp: return a proper error message when indexing out of range
This helps debug issues inside interp.
1 parent c8f77d2 commit 9951eb9

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

interp/interpreter.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,11 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
427427
if err != nil {
428428
return nil, mem, r.errorAt(inst, err)
429429
}
430-
methodSetPtr, err := mem.load(typecodePtr.addOffset(-int64(r.pointerSize)), r.pointerSize).asPointer(r)
430+
typecodePtrOffset, err := typecodePtr.addOffset(-int64(r.pointerSize))
431+
if err != nil {
432+
return nil, mem, r.errorAt(inst, err) // unlikely
433+
}
434+
methodSetPtr, err := mem.load(typecodePtrOffset, r.pointerSize).asPointer(r)
431435
if err != nil {
432436
return nil, mem, r.errorAt(inst, err)
433437
}
@@ -473,7 +477,11 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
473477
if err != nil {
474478
return nil, mem, r.errorAt(inst, err)
475479
}
476-
methodSetPtr, err := mem.load(typecodePtr.addOffset(-int64(r.pointerSize)), r.pointerSize).asPointer(r)
480+
typecodePtrOffset, err := typecodePtr.addOffset(-int64(r.pointerSize))
481+
if err != nil {
482+
return nil, mem, r.errorAt(inst, err)
483+
}
484+
methodSetPtr, err := mem.load(typecodePtrOffset, r.pointerSize).asPointer(r)
477485
if err != nil {
478486
return nil, mem, r.errorAt(inst, err)
479487
}
@@ -658,7 +666,10 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
658666
locals[inst.localIndex] = makeLiteralInt(ptrValue, int(operands[0].len(r)*8))
659667
continue
660668
}
661-
ptr = ptr.addOffset(int64(offset))
669+
ptr, err = ptr.addOffset(int64(offset))
670+
if err != nil {
671+
return nil, mem, r.errorAt(inst, err)
672+
}
662673
locals[inst.localIndex] = ptr
663674
if r.debug {
664675
fmt.Fprintln(os.Stderr, indent+"gep:", operands, "->", ptr)
@@ -756,7 +767,10 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
756767
if inst.opcode == llvm.Add {
757768
// This likely means this is part of a
758769
// unsafe.Pointer(uintptr(ptr) + offset) pattern.
759-
lhsPtr = lhsPtr.addOffset(int64(rhs.Uint()))
770+
lhsPtr, err = lhsPtr.addOffset(int64(rhs.Uint()))
771+
if err != nil {
772+
return nil, mem, r.errorAt(inst, err)
773+
}
760774
locals[inst.localIndex] = lhsPtr
761775
} else if inst.opcode == llvm.Xor && rhs.Uint() == 0 {
762776
// Special workaround for strings.noescape, see

interp/memory.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -517,12 +517,12 @@ func (v pointerValue) offset() uint32 {
517517
// addOffset essentially does a GEP operation (pointer arithmetic): it adds the
518518
// offset to the pointer. It also checks that the offset doesn't overflow the
519519
// maximum offset size (which is 4GB).
520-
func (v pointerValue) addOffset(offset int64) pointerValue {
520+
func (v pointerValue) addOffset(offset int64) (pointerValue, error) {
521521
result := pointerValue{v.pointer + uint64(offset)}
522522
if checks && v.index() != result.index() {
523-
panic("interp: offset out of range")
523+
return result, fmt.Errorf("interp: offset %d out of range for object %v", offset, v)
524524
}
525-
return result
525+
return result, nil
526526
}
527527

528528
func (v pointerValue) len(r *runner) uint32 {

0 commit comments

Comments
 (0)