aboutsummaryrefslogtreecommitdiffhomepage
path: root/interp
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2023-05-20 17:17:54 +0200
committerRon Evans <[email protected]>2023-05-20 23:57:20 +0200
commitcf39db36fea07c7b35e50e47f6c76d4c3f15100e (patch)
tree931049c471ea75376c0b2e169bc3d91e46af1a61 /interp
parent54c07b7de81d04cda442bee10dabdb8cdb9a1e58 (diff)
downloadtinygo-cf39db36fea07c7b35e50e47f6c76d4c3f15100e.tar.gz
tinygo-cf39db36fea07c7b35e50e47f6c76d4c3f15100e.zip
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.
Diffstat (limited to 'interp')
-rw-r--r--interp/interpreter.go21
1 files changed, 8 insertions, 13 deletions
diff --git a/interp/interpreter.go b/interp/interpreter.go
index 46aa9d1f4..1ec4597e1 100644
--- a/interp/interpreter.go
+++ b/interp/interpreter.go
@@ -736,30 +736,25 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
if err == nil {
// The lhs is a pointer. This sometimes happens for particular
// pointer tricks.
- switch inst.opcode {
- case llvm.Add:
+ if inst.opcode == llvm.Add {
// This likely means this is part of a
// unsafe.Pointer(uintptr(ptr) + offset) pattern.
lhsPtr = lhsPtr.addOffset(int64(rhs.Uint()))
locals[inst.localIndex] = lhsPtr
- continue
- case llvm.Xor:
- if rhs.Uint() == 0 {
- // Special workaround for strings.noescape, see
- // src/strings/builder.go in the Go source tree. This is
- // the identity operator, so we can return the input.
- locals[inst.localIndex] = lhs
- continue
- }
- default:
+ } else if inst.opcode == llvm.Xor && rhs.Uint() == 0 {
+ // Special workaround for strings.noescape, see
+ // src/strings/builder.go in the Go source tree. This is
+ // the identity operator, so we can return the input.
+ locals[inst.localIndex] = lhs
+ } else {
// Catch-all for weird operations that should just be done
// at runtime.
err := r.runAtRuntime(fn, inst, locals, &mem, indent)
if err != nil {
return nil, mem, err
}
- continue
}
+ continue
}
var result uint64
switch inst.opcode {