Skip to content

Fix computed goto into statement expression (undefined behavior)#7

Merged
guillerodriguez merged 1 commit intomasterfrom
fix/interp-computed-goto
Feb 5, 2026
Merged

Fix computed goto into statement expression (undefined behavior)#7
guillerodriguez merged 1 commit intomasterfrom
fix/interp-computed-goto

Conversation

@guillerodriguez
Copy link
Copy Markdown
Contributor

The DEF_OPC_JMP macros in interp-inlining.h place BRANCH labels inside GCC statement expressions ({ }). These labels are targets of computed gotos via the interpreter dispatch table. Per GCC documentation, jumping into a statement expression with a computed goto is undefined behavior 1, so this is fragile and not guaranteed to work.

Although GCC does detect this in some simple cases, it does not catch it in JamVM, possibly due to the way the code is structured (label addresses are collected into the dispatch table separately from the goto *pc->handler dispatch in the interpreter loop). Clang 17+ performs whole-function analysis of indirect goto targets and rejects the code with a hard error:

error: cannot jump from this indirect goto statement to one of
its possible targets
note: possible target of indirect goto statement
note: jump enters a statement expression

Only interp-inlining.h is affected. The other interpreter variants (interp-direct.h, interp-indirect.h) do not create labels inside statement expressions in their BRANCH macros.

Fix by changing ({ }) to { } in DEF_OPC_JMP. The statement expression return value was never used (BODY is in statement context and always exits via goto *pc->handler), so the change is purely syntactic. Double checked that GCC produces byte-identical machine code with and without this change for all optimization levels.

The DEF_OPC_JMP macros in interp-inlining.h place BRANCH labels
inside GCC statement expressions ({ }). These labels are targets
of computed gotos via the interpreter dispatch table. Per GCC
documentation, jumping into a statement expression with a computed
goto is undefined behavior [1], so this is fragile and not
guaranteed to work.

Although GCC does detect this in some simple cases, it does not
catch it in JamVM, possibly due to the way the code is structured
(label addresses are collected into the dispatch table separately
from the goto *pc->handler dispatch in the interpreter loop).
Clang 17+ performs whole-function analysis of indirect goto targets
and rejects the code with a hard error:

  error: cannot jump from this indirect goto statement to one of
         its possible targets
  note:  possible target of indirect goto statement
  note:  jump enters a statement expression

Only interp-inlining.h is affected. The other interpreter variants
(interp-direct.h, interp-indirect.h) do not create labels inside
statement expressions in their BRANCH macros.

Fix by changing ({ }) to { } in DEF_OPC_JMP. The statement
expression return value was never used (BODY is in statement context
and always exits via goto *pc->handler), so the change is purely
syntactic. Double checked that GCC produces byte-identical machine
code with and without this change for all optimization levels.

 [1]: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html

Signed-off-by: Guillermo Rodríguez <grodriguez@ingelabs.com>
@guillerodriguez
Copy link
Copy Markdown
Contributor Author

From GCC documentation:

Jumping into a statement expression with goto or using a switch statement outside the statement expression with a case or default label inside the statement expression is not permitted. Jumping into a statement expression with a computed goto (see Labels as Values) has undefined behavior.

@guillerodriguez guillerodriguez merged commit 70b7fe4 into master Feb 5, 2026
3 checks passed
@guillerodriguez guillerodriguez deleted the fix/interp-computed-goto branch February 5, 2026 12:35
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.

2 participants