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.
Этот коммит содержится в:
родитель
54c07b7de8
коммит
cf39db36fe
1 изменённых файлов: 8 добавлений и 13 удалений
|
@ -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:
|
|
||||||
if rhs.Uint() == 0 {
|
|
||||||
// Special workaround for strings.noescape, see
|
// Special workaround for strings.noescape, see
|
||||||
// src/strings/builder.go in the Go source tree. This is
|
// src/strings/builder.go in the Go source tree. This is
|
||||||
// the identity operator, so we can return the input.
|
// the identity operator, so we can return the input.
|
||||||
locals[inst.localIndex] = lhs
|
locals[inst.localIndex] = lhs
|
||||||
continue
|
} else {
|
||||||
}
|
|
||||||
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 {
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче