Skip to content

c2mir: address-taken narrow integer value not sign/zero-extended (wrong result under -ei) #458

Description

@derekbsnider

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions