Fix/ny msize dse expansion (#565)

Bug found by @jubnzv:

`--newyork`: dead-store elimination could drop a store whose memory
expansion an intervening `msize()` observes, so `msize()` read a stale
(unexpanded) value.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
xermicusandClaude Opus 4.8 authored and GitHub committed 2026-07-08 16:31:01 +02:00
1 parent 9adfd9db24
commit e2e6514953
4 files changed
+112

No files matched your search

+22
View File
@@ -4769,6 +4769,28 @@ fn array_bounds_probe() {
}
}
/// Regression (newyork dead-store elimination vs `msize`): a store whose memory
/// expansion an intervening `msize()` observes must not be eliminated as dead.
/// `mstore(288, 1); let r := msize(); mstore(288, 2)` — the dead-store pass
/// dropped the first store as overwritten by the second, moving the memory
/// expansion to after the `msize()`, so `r` read the smaller value `0` instead of
/// `0x140`. The fix clears the dead-store candidate set at an `msize()`, which
/// observes the cumulative expansion of all prior stores. Compared newyork-PVM
/// vs solc-EVM.
#[test]
fn msize_observes_dead_store_expansion() {
let mut actions = instantiate_yul("contracts/MsizeDseBug.yul", "MsizeDseBug");
actions.push(Call {
origin: TestAddress::Alice,
dest: TestAddress::Instantiated(0),
value: 0,
gas_limit: Some(GAS_LIMIT),
storage_deposit_limit: None,
data: vec![],
});
run_differential(actions);
}
/// Regression (newyork FMP range proof): a `calldatacopy` whose *dynamic*
/// destination can land on the free-memory-pointer word `[0x40, 0x60)` corrupts
/// the FMP, but only *static* copy destinations flagged `fmp_could_be_unbounded`.