Skip to content

interp: defer out-of-bounds loads to runtime instead of crashing#5458

Merged
deadprogram merged 1 commit into
tinygo-org:devfrom
iamrajiv:fix-interp-oob-load-4214
Jun 24, 2026
Merged

interp: defer out-of-bounds loads to runtime instead of crashing#5458
deadprogram merged 1 commit into
tinygo-org:devfrom
iamrajiv:fix-interp-oob-load-4214

Conversation

@iamrajiv

Copy link
Copy Markdown
Contributor

Fixes #4214

When the interpreter encountered a load that was out of bounds of the object, it panicked with "interp: load out of bounds", crashing the compiler. This can happen for valid Go programs, for example when dereferencing the pointer returned by unsafe.SliceData on a zero-capacity slice, which points to a zero-sized object:

package main

import "unsafe"

var p = unsafe.SliceData([]int{})
var v = *p

func main() {}

Return nil for an out-of-bounds load, the same as for an external global, so the caller defers the load to runtime instead of crashing. This matches what regular Go does, where the load reads from the runtime zero-base at runtime.

When the interpreter encountered a load that was out of bounds of the
object, it panicked with "interp: load out of bounds", crashing the
compiler. This can happen for valid Go programs, for example when
dereferencing the pointer returned by unsafe.SliceData on a
zero-capacity slice, which points to a zero-sized object:

	package main

	import "unsafe"

	var p = unsafe.SliceData([]int{})
	var v = *p

	func main() {}

Return nil for an out-of-bounds load, the same as for an external
global, so the caller defers the load to runtime instead of crashing.
This matches what regular Go does, where the load reads from the
runtime zero-base at runtime.

Fixes tinygo-org#4214
@dgryski

dgryski commented Jun 11, 2026

Copy link
Copy Markdown
Member

/cc @aykevl for interp

@jakebailey jakebailey left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on my own (limited) experience in interp, this seems right to me? e.g. in my PR to limit interp iterations bailing out is the right way to get it to do something at runtime instead. The only reason this code should panic is for internal errors, not because the user code does something that will panic at runtime.

@deadprogram

Copy link
Copy Markdown
Member

@aykevl or anyone else have any feedback here?

@deadprogram

deadprogram commented Jun 24, 2026

Copy link
Copy Markdown
Member

Based on previous feedback from @niaow since this is undefined behavior, we probably should not do what is in this PR? Not sure on that, however.

@jakebailey

Copy link
Copy Markdown
Member

It is, but I don't think bad code should crash the compiler

@aykevl aykevl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. It doesn't add undefined behavior, it just bails and defers to runtime (where the panic should be caught).

@deadprogram

Copy link
Copy Markdown
Member

Thank you for the fix @iamrajiv and to everyone who reviewed. Now merging!

@deadprogram deadprogram merged commit f166976 into tinygo-org:dev Jun 24, 2026
20 of 21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

panic: interp: load out of bounds on unsafe.SliceData of zero cap slice

5 participants