force_val does not sign/zero-extend the value of a narrow integer (i8/u8/i16/u16) variable held in a register, so reading an address-taken signed char / short (etc.) can yield a non-extended value under the interpreter.
Reproducer
static void set_schar (signed char *p) { *p = -3; }
static void set_ushort (unsigned short *p) { *p = 65535; }
int main (void) {
signed char sc; unsigned short us;
set_schar (&sc);
set_ushort (&us);
if (sc != -3) return 2;
if (us != 65535) return 3;
return 0;
}
./c2m repro.c -ei returns 2 (sc not sign-extended). With the fix, 0.
Fix
In force_val, when the operand is a register of a narrow integer type, cast it to that type (i8/u8/i16/u16) so the value is properly extended.
🤖 Found during a source review with Claude Code
Fix in #459.
force_valdoes not sign/zero-extend the value of a narrow integer (i8/u8/i16/u16) variable held in a register, so reading an address-takensigned char/short(etc.) can yield a non-extended value under the interpreter.Reproducer
./c2m repro.c -eireturns 2 (scnot sign-extended). With the fix, 0.Fix
In
force_val, when the operand is a register of a narrow integer type, cast it to that type (i8/u8/i16/u16) so the value is properly extended.🤖 Found during a source review with Claude Code
Fix in #459.