interp: fix subtle bug in pointer xor

If a pointer value was xor'ed with a value other than 0, it would not
have been run at runtime but instead would fall through to the generic
integer operations. This would likely result in a "cannot convert
pointer to integer" panic.

This commit fixes this subtle case.
Этот коммит содержится в:
Ayke van Laethem 2023-05-20 17:17:54 +02:00 коммит произвёл Ron Evans
родитель 54c07b7de8
коммит cf39db36fe

Просмотреть файл

@ -736,30 +736,25 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
if err == nil { if err == nil {
// The lhs is a pointer. This sometimes happens for particular // The lhs is a pointer. This sometimes happens for particular
// pointer tricks. // pointer tricks.
switch inst.opcode { if inst.opcode == llvm.Add {
case 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 = lhsPtr.addOffset(int64(rhs.Uint()))
locals[inst.localIndex] = lhsPtr locals[inst.localIndex] = lhsPtr
continue } else if inst.opcode == llvm.Xor && rhs.Uint() == 0 {
case llvm.Xor: // Special workaround for strings.noescape, see
if rhs.Uint() == 0 { // src/strings/builder.go in the Go source tree. This is
// Special workaround for strings.noescape, see // the identity operator, so we can return the input.
// src/strings/builder.go in the Go source tree. This is locals[inst.localIndex] = lhs
// the identity operator, so we can return the input. } else {
locals[inst.localIndex] = lhs
continue
}
default:
// Catch-all for weird operations that should just be done // Catch-all for weird operations that should just be done
// at runtime. // at runtime.
err := r.runAtRuntime(fn, inst, locals, &mem, indent) err := r.runAtRuntime(fn, inst, locals, &mem, indent)
if err != nil { if err != nil {
return nil, mem, err return nil, mem, err
} }
continue
} }
continue
} }
var result uint64 var result uint64
switch inst.opcode { switch inst.opcode {