Add casts to u32 before left shifts to address ubsan edge cases.

Common idiom that wasn't always applied, especially in emit.c and
cfuns.c
This commit is contained in:
Calvin Rose committed 2026-06-27 14:26:57 -05:00
1 parent 88c42fff48
commit 8dbe828504
7 files changed
+45 -34

No files matched your search

+2 -2
View File
@@ -188,7 +188,7 @@ static JanetSlot do_get(JanetFopts opts, JanetSlot *args) {
janetc_copy(c, t, dflt_slot);
if (target_is_default) janetc_freeslot(c, dflt_slot);
int32_t current = janet_v_count(c->buffer);
c->buffer[label] |= (current - label) << 16;
c->buffer[label] |= (uint32_t)(current - label) << 16;
return t;
} else {
return opreduce(opts, args, JOP_GET, 0, janet_wrap_nil(), janet_wrap_nil());
@@ -345,7 +345,7 @@ static JanetSlot compreduce(
int32_t end = janet_v_count(c->buffer);
for (i = 0; i < janet_v_count(labels); i++) {
int32_t label = labels[i];
c->buffer[label] |= ((end - label) << 16);
c->buffer[label] |= ((uint32_t)(end - label) << 16);
}
janet_v_free(labels);
return t;
+5 -1
View File
@@ -280,7 +280,11 @@ Shadowing janetc_shadowcheck(JanetCompiler *c, const uint8_t *sym) {
for (int32_t i = len - 1; i >= 0; i--) {
SymPair *pair = scope->syms + i;
if (pair->sym == sym) {
janet_assert(!is_global, "shadowing analysis is incorrect. compiler bug");
if (is_global) {
/* This can happen in a top level form like (def [x [x y]] [1 [2 3]])` where a symbol is reused in one expression */
/* janet_assert(!is_global, "shadowing analysis is incorrect. compiler bug"); */
return JANETC_SHADOW_GLOBAL_HIDES_GLOBAL;
}
return JANETC_SHADOW_LOCAL_HIDES_LOCAL;
}
}
+10 -7
View File
@@ -441,19 +441,22 @@ JANET_CORE_FN(janet_core_range,
start = janet_getnumber(argv, 0);
stop = janet_getnumber(argv, 1);
step = janet_getnumber(argv, 2);
count = (step > 0) ? (stop - start) / step :
((step < 0) ? (stop - start) / step : 0);
count = (step > 0.0) ? (stop - start) / step :
((step < 0.0) ? (stop - start) / step : 0.0);
} else if (argc == 2) {
start = janet_getnumber(argv, 0);
stop = janet_getnumber(argv, 1);
start = janet_getnumber(argv, 0.0);
stop = janet_getnumber(argv, 1.0);
count = stop - start;
} else {
stop = janet_getnumber(argv, 0);
stop = janet_getnumber(argv, 0.0);
count = stop;
}
count = (count > 0) ? count : 0;
if (isinf(step)) {
janet_panic("infinite step not allowed");
}
count = (count > 0.0) ? count : 0.0;
int32_t int_count;
janet_assert(count >= 0, "bad range code");
janet_assert(count >= 0.0, "bad range code");
if (count > (double) INT32_MAX) {
janet_panicf("range is too large, %f elements", count);
} else {
+17 -17
View File
@@ -78,10 +78,10 @@ static int32_t janetc_const(JanetCompiler *c, Janet x) {
static void janetc_loadconst(JanetCompiler *c, Janet k, int32_t reg) {
switch (janet_type(k)) {
case JANET_NIL:
janetc_emit(c, (reg << 8) | JOP_LOAD_NIL);
janetc_emit(c, ((uint32_t) reg << 8) | JOP_LOAD_NIL);
break;
case JANET_BOOLEAN:
janetc_emit(c, (reg << 8) |
janetc_emit(c, ((uint32_t) reg << 8) |
(janet_unwrap_boolean(k) ? JOP_LOAD_TRUE : JOP_LOAD_FALSE));
break;
case JANET_NUMBER: {
@@ -93,8 +93,8 @@ static void janetc_loadconst(JanetCompiler *c, Janet k, int32_t reg) {
goto do_constant;
uint32_t iu = (uint32_t)i;
janetc_emit(c,
(iu << 16) |
(reg << 8) |
((uint32_t) iu << 16) |
((uint32_t) reg << 8) |
JOP_LOAD_INTEGER);
break;
}
@@ -102,8 +102,8 @@ static void janetc_loadconst(JanetCompiler *c, Janet k, int32_t reg) {
do_constant: {
int32_t cindex = janetc_const(c, k);
janetc_emit(c,
(cindex << 16) |
(reg << 8) |
((uint32_t) cindex << 16) |
((uint32_t) reg << 8) |
JOP_LOAD_CONSTANT);
break;
}
@@ -120,8 +120,8 @@ static void janetc_movenear(JanetCompiler *c,
/* If we also are a reference, deref the one element array */
if (src.flags & JANET_SLOT_REF) {
janetc_emit(c,
(dest << 16) |
(dest << 8) |
((uint32_t) dest << 16) |
((uint32_t) dest << 8) |
JOP_GET_INDEX);
}
} else if (src.envindex >= 0) {
@@ -147,15 +147,15 @@ static void janetc_moveback(JanetCompiler *c,
int32_t refreg = janetc_regalloc_temp(&c->scope->ra, JANETC_REGTEMP_5);
janetc_loadconst(c, dest.constant, refreg);
janetc_emit(c,
(src << 16) |
(refreg << 8) |
((uint32_t) src << 16) |
((uint32_t) refreg << 8) |
JOP_PUT_INDEX);
janetc_regalloc_freetemp(&c->scope->ra, refreg, JANETC_REGTEMP_5);
} else if (dest.envindex >= 0) {
/* Convert src to near reg */
if (src > 255) {
int32_t newsrc = JANETC_REGTEMP_5 + 0xF0;
janetc_emit(c, JOP_MOVE_NEAR | ((uint32_t)(src) << 16) | (newsrc << 8));
janetc_emit(c, JOP_MOVE_NEAR | ((uint32_t)(src) << 16) | ((uint32_t) newsrc << 8));
src = newsrc;
}
janetc_emit(c,
@@ -199,7 +199,7 @@ static int32_t janetc_regfar(JanetCompiler *c, JanetSlot s, JanetcRegisterTemp t
janetc_movenear(c, nearreg, s);
if (nearreg >= 0xF0) {
reg = janetc_allocfar(c);
janetc_emit(c, JOP_MOVE_FAR | (nearreg << 8) | (reg << 16));
janetc_emit(c, JOP_MOVE_FAR | ((uint32_t) nearreg << 8) | ((uint32_t) reg << 16));
janetc_regalloc_freetemp(&c->scope->ra, nearreg, tag);
} else {
reg = nearreg;
@@ -268,7 +268,7 @@ void janetc_copy(
static int32_t emit1s(JanetCompiler *c, uint8_t op, JanetSlot s, int32_t rest, int wr) {
int32_t reg = janetc_regnear(c, s, JANETC_REGTEMP_0);
int32_t label = janet_v_count(c->buffer);
janetc_emit(c, op | (reg << 8) | ((uint32_t)rest << 16));
janetc_emit(c, op | ((uint32_t) reg << 8) | ((uint32_t) rest << 16));
if (wr)
janetc_moveback(c, s, reg);
janetc_free_regnear(c, s, reg, JANETC_REGTEMP_0);
@@ -278,7 +278,7 @@ static int32_t emit1s(JanetCompiler *c, uint8_t op, JanetSlot s, int32_t rest, i
int32_t janetc_emit_s(JanetCompiler *c, uint8_t op, JanetSlot s, int wr) {
int32_t reg = janetc_regfar(c, s, JANETC_REGTEMP_0);
int32_t label = janet_v_count(c->buffer);
janetc_emit(c, op | (reg << 8));
janetc_emit(c, op | ((uint32_t) reg << 8));
if (wr)
janetc_moveback(c, s, reg);
janetc_free_regnear(c, s, reg, JANETC_REGTEMP_0);
@@ -310,7 +310,7 @@ static int32_t emit2s(JanetCompiler *c, uint8_t op, JanetSlot s1, JanetSlot s2,
int32_t reg1 = janetc_regnear(c, s1, JANETC_REGTEMP_0);
int32_t reg2 = janetc_regnear(c, s2, JANETC_REGTEMP_1);
int32_t label = janet_v_count(c->buffer);
janetc_emit(c, op | (reg1 << 8) | (reg2 << 16) | ((uint32_t)rest << 24));
janetc_emit(c, op | ((uint32_t) reg1 << 8) | ((uint32_t) reg2 << 16) | ((uint32_t)rest << 24));
janetc_free_regnear(c, s2, reg2, JANETC_REGTEMP_1);
if (wr)
janetc_moveback(c, s1, reg1);
@@ -322,7 +322,7 @@ int32_t janetc_emit_ss(JanetCompiler *c, uint8_t op, JanetSlot s1, JanetSlot s2,
int32_t reg1 = janetc_regnear(c, s1, JANETC_REGTEMP_0);
int32_t reg2 = janetc_regfar(c, s2, JANETC_REGTEMP_1);
int32_t label = janet_v_count(c->buffer);
janetc_emit(c, op | (reg1 << 8) | (reg2 << 16));
janetc_emit(c, op | ((uint32_t) reg1 << 8) | ((uint32_t) reg2 << 16));
janetc_free_regnear(c, s2, reg2, JANETC_REGTEMP_1);
if (wr)
janetc_moveback(c, s1, reg1);
@@ -343,7 +343,7 @@ int32_t janetc_emit_sss(JanetCompiler *c, uint8_t op, JanetSlot s1, JanetSlot s2
int32_t reg2 = janetc_regnear(c, s2, JANETC_REGTEMP_1);
int32_t reg3 = janetc_regnear(c, s3, JANETC_REGTEMP_2);
int32_t label = janet_v_count(c->buffer);
janetc_emit(c, op | (reg1 << 8) | (reg2 << 16) | ((uint32_t)reg3 << 24));
janetc_emit(c, op | ((uint32_t) reg1 << 8) | ((uint32_t) reg2 << 16) | ((uint32_t) reg3 << 24));
janetc_free_regnear(c, s2, reg2, JANETC_REGTEMP_1);
janetc_free_regnear(c, s3, reg3, JANETC_REGTEMP_2);
if (wr)
+7 -7
View File
@@ -723,10 +723,10 @@ static JanetSlot janetc_if(JanetFopts opts, int32_t argn, const Janet *argv) {
labeld = janet_v_count(c->buffer);
if (labeljr < labeld) {
check_16bit_jump(c, labeljr, labelr);
c->buffer[labeljr] |= (labelr - labeljr) << 16;
c->buffer[labeljr] |= (uint32_t) (labelr - labeljr) << 16;
if (!tail && labeljd < labeld) {
check_24bit_jump(c, labeljd, labeld);
c->buffer[labeljd] |= (labeld - labeljd) << 8;
c->buffer[labeljd] |= (uint32_t) (labeld - labeljd) << 8;
}
}
@@ -945,8 +945,8 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
}
/* But now add tail recursion */
int32_t tempself = janetc_regalloc_temp(&tempscope.ra, JANETC_REGTEMP_0);
janetc_emit(c, JOP_LOAD_SELF | (tempself << 8));
janetc_emit(c, JOP_TAILCALL | (tempself << 8));
janetc_emit(c, JOP_LOAD_SELF | ((uint32_t) tempself << 8));
janetc_emit(c, JOP_TAILCALL | ((uint32_t) tempself << 8));
janetc_regalloc_freetemp(&c->scope->ra, tempself, JANETC_REGTEMP_0);
/* Compile function */
JanetFuncDef *def = janetc_pop_funcdef(c);
@@ -955,8 +955,8 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
int32_t defindex = janetc_addfuncdef(c, def);
/* And then load the closure and call it. */
int32_t cloreg = janetc_regalloc_temp(&c->scope->ra, JANETC_REGTEMP_0);
janetc_emit(c, JOP_CLOSURE | (cloreg << 8) | (defindex << 16));
janetc_emit(c, JOP_CALL | (cloreg << 8) | (cloreg << 16));
janetc_emit(c, JOP_CLOSURE | ((uint32_t) cloreg << 8) | ((uint32_t) defindex << 16));
janetc_emit(c, JOP_CALL | ((uint32_t) cloreg << 8) | ((uint32_t) cloreg << 16));
janetc_regalloc_freetemp(&c->scope->ra, cloreg, JANETC_REGTEMP_0);
c->scope->flags |= JANET_SCOPE_CLOSURE;
return janetc_cslot(janet_wrap_nil());
@@ -980,7 +980,7 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
for (int32_t i = labelwt; i < labeld; i++) {
if (c->buffer[i] == (0x80 | JOP_JUMP)) {
check_24bit_jump(c, i, labeld);
c->buffer[i] = JOP_JUMP | ((labeld - i) << 8);
c->buffer[i] = JOP_JUMP | ((uint32_t) (labeld - i) << 8);
}
}
+2
View File
@@ -156,4 +156,6 @@
(check-lint-compile '(let [outer1 "b"] outer1) "shadow local-to-global")
(check-lint-compile '(do (def x "b") (def x "c")) "shadow local-to-local")
(check-lint-compile '(def [xxx [xxx yyy]] [1 [2 3]]) "shadow global-to-global one form")
(end-suite)
+2
View File
@@ -207,4 +207,6 @@
'(fn :short-fn [] (set (my-table [2 1]) (quote foo))))
"Macro expand inside set preserves tuple type correctly")
(assert-error "no infinite step range" (range 3 3 math/inf))
(end-suite)