Skip to content

Commit 4e6dc98

Browse files
leifericfclaude
andcommitted
v0.144.2: mark setjmp-adjacent locals volatile to satisfy gcc
gcc's -Werror=clobbered flagged three locals in mino_bc_run that could be modified between setjmp and the matching longjmp return: the env parameter, the rest cons-list local in the variadic dispatch, and the t local inside the inlined mino_current_ctx. Apple clang on macOS doesn't emit this warning so local builds were green; the Linux CI build (gcc 12) failed at cc1: all warnings being treated as errors. Marks env and rest volatile in mino_bc_run and replaces the post-setjmp mino_current_ctx(S) call with the captured ctx local from before the try frame. Hot path is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 8a659f8 commit 4e6dc98

3 files changed

Lines changed: 24 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
# Changelog
22

3+
## v0.144.2 — Build Fix: Mark setjmp-Adjacent Locals `volatile`
4+
5+
GCC's `-Werror=clobbered` flagged three locals in `mino_bc_run`
6+
that could be modified between `setjmp` and a matching `longjmp`
7+
return: the `env` parameter (rewritten on catch-frame unwind),
8+
the `rest` cons-list local in the variadic dispatch (built before
9+
setjmp and read after), and the `t` local inside the inlined
10+
`mino_current_ctx` (reached after setjmp via a TLS load + branch).
11+
Apple clang doesn't emit this warning so local builds were
12+
green; the Linux CI build (gcc 12) failed at `cc1: all warnings
13+
being treated as errors`.
14+
15+
The fix marks `env` and `rest` `volatile` in `mino_bc_run` and
16+
replaces the second `mino_current_ctx(S)` call after `setjmp`
17+
with the already-captured `ctx` local that was set before the
18+
try frame. The hot path is unchanged: `ctx` reads the same TLS
19+
slot once at fn entry; the `volatile`-marked locals only matter
20+
to the compiler's analysis, not to the emitted code.
21+
322
## v0.144.1 — GC Fix: Compiled Bytecode Children Traced Via Remset
423

524
The compiled-bytecode record (`mino_bc_fn_t`) was allocated as

src/eval/bc/vm.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ static mino_val_t *resolve_global(mino_state_t *S, mino_val_t *sym,
238238
}
239239

240240
mino_val_t *mino_bc_run(mino_state_t *S, mino_val_t *fn_val,
241-
mino_val_t **argv, int argc, mino_env_t *env)
241+
mino_val_t **argv, int argc,
242+
mino_env_t *volatile env)
242243
{
243244
const mino_bc_fn_t *bc = fn_val->as.fn.bc;
244245
if (bc == NULL || bc->code == NULL) return NULL;
@@ -272,7 +273,7 @@ mino_val_t *mino_bc_run(mino_state_t *S, mino_val_t *fn_val,
272273
* we get the values in their original order. When argc ==
273274
* n_params the rest binding is the empty list. */
274275
if (match->has_rest) {
275-
mino_val_t *rest = mino_nil(S);
276+
mino_val_t *volatile rest = mino_nil(S);
276277
for (int i = argc - 1; i >= match->n_params; i--) {
277278
rest = mino_cons(S, argv[i], rest);
278279
if (rest == NULL) { bc_pop_window(S, base); return NULL; }
@@ -382,7 +383,7 @@ mino_val_t *mino_bc_run(mino_state_t *S, mino_val_t *fn_val,
382383
unsigned bx = Bx_OF(ins);
383384
if ((int)bx >= bc->ic_slots_len) { ok = 0; goto bc_done; }
384385
mino_bc_ic_slot_t *slot = &bc->ic_slots[bx];
385-
int dyn_active = (mino_current_ctx(S)->dyn_stack != NULL);
386+
int dyn_active = (ctx->dyn_stack != NULL);
386387
if (!dyn_active
387388
&& slot->cached != NULL
388389
&& slot->gen == S->ic_gen) {

src/mino.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
*/
2929
#define MINO_VERSION_MAJOR 0
3030
#define MINO_VERSION_MINOR 144
31-
#define MINO_VERSION_PATCH 1
31+
#define MINO_VERSION_PATCH 2
3232

3333
/*
3434
* Human-readable version string of the *linked* runtime, e.g. "0.48.0".

0 commit comments

Comments
 (0)