Consider this code from core.lifetime: void copyEmplacex(ref immutable(S) source, ref immutable(S) target) @system { import core.stdc.string : memcpy; memcpy(cast(S*) &target, cast(S*) &source, S.sizeof); (cast() target).__xpostblit(); } Note the last line casts away immutability, and the call to __xpostblit() modifies the supposedly immutable `target`. The part of the optimizer that fails this is the function Symbol_isAffected() in backend/symbol.d The fix is to set a flag in `funcsym_p` when it is @safe, and enable the check for immutability.
@WalterBright created dlang/dmd pull request #12424 "fix Issue 21821 - Optimizer assumes immutables do not change, but the…" fixing this issue: - fix Issue 21821 - Optimizer assumes immutables do not change, but they can in @system code https://github.com/dlang/dmd/pull/12424
Where is this specified ? `immutable` should never change, that's the point! I've never seen, nor heard, that `immutable` could be violated in `@system`. This code in `core.lifetime` exhibits UB and should be changed to apply `immutable` after the `memcpy`, e.g. as `assummeUnique` does.
dlang/dmd pull request #12424 "fix Issue 21821 - Optimizer assumes immutables do not change, but the…" was merged into master: - ba1f1c3222a91ef6a56caa18afa3bf7464d9e422 by Walter Bright: fix Issue 21821 - Optimizer assumes immutables do not change, but they can in @system code https://github.com/dlang/dmd/pull/12424