Skip to content

c2mir: reading an uninitialized narrow local can yield an out-of-range value under MIR-gen (-O0/-O1) #461

Description

@derekbsnider

First, thank you for the quick handling of #458 and for the follow-up that kept reads of narrow register values extension-free — that is clearly the right call for generated-code quality, and we have adopted the same approach.

While testing against gcc.c-torture we found one corner case that slips past it: char x; x / 1000 can return nonzero, although whatever indeterminate value x holds should still be within char range. execute/pr34099-2.c aborts with ./c2m -O0 pr34099-2.c -eg (also -O1; -O2 happens to pass because constant folding masks it).

The extension-free reads rely on a narrow reg value always being born from an extending operation. An uninitialized local's pseudo-reg was never stored to at all, so it carries whatever stale 64-bit value the register held. The invariant itself seems well worth keeping — a small proposed fix that repairs this at the declaration site follows in a PR, and of course we are happy to rework it if you would prefer a different approach.

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