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.
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 / 1000can return nonzero, although whatever indeterminate valuexholds should still be within char range.execute/pr34099-2.caborts with./c2m -O0 pr34099-2.c -eg(also-O1;-O2happens 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.