Skip to content

Commit 5bb61ad

Browse files
committed
vm_eval.c: Preserve rb_iterate0 locals across longjmp
Clang 17 at -O1 with -fPIC can incorrectly rematerialize cfp after longjmp when a nearby stack layout changes, even though cfp is not modified in the tag region. This makes rb_iterate0 miss the matching escape frame and propagate TAG_BREAK as an unexpected break. Copy the ec argument into a volatile local and make the saved cfp volatile so both values are reloaded from their pre-setjmp storage. This keeps the direct ZJIT fields added by ruby#17953. This is the rb_iterate0 portion of ruby#17931.
1 parent 9db590e commit 5bb61ad

1 file changed

Lines changed: 3 additions & 2 deletions

File tree

vm_eval.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,11 +1479,12 @@ vm_frametype_name(const rb_control_frame_t *cfp);
14791479
static VALUE
14801480
rb_iterate0(VALUE (* it_proc) (VALUE), VALUE data1,
14811481
const struct vm_ifunc *const ifunc,
1482-
rb_execution_context_t *ec)
1482+
rb_execution_context_t *ec_arg)
14831483
{
14841484
enum ruby_tag_type state;
14851485
volatile VALUE retval = Qnil;
1486-
rb_control_frame_t *const cfp = ec->cfp;
1486+
rb_execution_context_t * volatile ec = ec_arg;
1487+
rb_control_frame_t *volatile const cfp = ec->cfp;
14871488

14881489
EC_PUSH_TAG(ec);
14891490
state = EC_EXEC_TAG();

0 commit comments

Comments
 (0)