Bug 21513 – [Reg 2.094.1] Slice assignment segmentation fault

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2020-12-29T09:04:05Z
Last change time
2021-02-13T12:29:55Z
Keywords
backend, pull, wrong-code
Assigned to
No Owner
Creator
thomas.bockman

Comments

Comment #0 by thomas.bockman — 2020-12-29T09:04:05Z
This fails on recent dmd versions with -debug: ///////////////////////////////////////////////////////////////////////// module app; struct Stuff { size_t capacity; size_t[1] items; void grow() { const oldCapacity = capacity; items.ptr[0 .. oldCapacity] = items.ptr[0 .. oldCapacity]; items.ptr[oldCapacity .. 1] = 0; // Segmentation fault (code -11) } } void main() { Stuff stuff; stuff.grow(); } //////////////////////////////////////////////////////////////////////// run.dlang.io's "All dmd compilers (2.060 - latest)" mode claims the problem started in 2.094.1: Up to 2.093.1: Success and no output Since 2.094.1: Failure with output: Error: program killed by signal 11
Comment #1 by thomas.bockman — 2020-12-29T09:05:58Z
Note that it works if the second slice assignment is replaced with an equivalent manual loop.
Comment #2 by razvan.nitu1305 — 2021-02-01T16:32:07Z
This is weird. I cannot reproduce locally with git master. Running on run.dlang.io does indeed seem to produce the segfault, however, if I select dmd, dmd-beta, dmd-nightly the issue does not occur. Is it possible that this issue has been fixed?
Comment #3 by b2.temp — 2021-02-02T10:03:03Z
Possibly caused by https://github.com/dlang/dmd/pull/11427. Based on this slightly modified TC: --- struct Stuff { size_t c; // declare after items and not crash ! ubyte[1] items; } void grow(ref Stuff stuff) { with (stuff) { const oldCapacity = c; items.ptr[0..oldCapacity] = items.ptr[0..0]; // use literal 0 instead of items.ptr[0] = 0; // oldcapacity and no crash ! } } void main() { Stuff stuff; grow(stuff); } --- before (2.092): --- _D7example4growFKSQq5StuffZv: push RBP mov RBP,RSP sub RSP,020h mov -8[RBP],RDI mov RAX,-8[RBP] mov -018h[RBP],RAX mov -018h[RBP],RAX mov RCX,[RAX] mov -010h[RBP],RCX mov RDX,-010h[RBP] lea RSI,8[RAX] mov RDI,RSI mov -020h[RBP],RSI call memcpy@PLT32 ; memcpy mov RAX,-020h[RBP] mov byte ptr [RAX],0 leave ret --- cg after (2.084.2): _D7example4growFKSQq5StuffZv: push RBP mov RBP,RSP sub RSP,020h mov -8[RBP],RDI mov RAX,-8[RBP] mov -018h[RBP],RAX mov -018h[RBP],RAX mov RCX,[RAX] mov -010h[RBP],RCX lea RSI,8[RAX] mov RCX,-010h[RBP] mov RDI,RSI test RCX,RCX je $+7h ; debug, break here, set ZF to 0 and no crash ! mov -020h[RBP],RSI ; b/c then the address that will end up in RAX is valid rep movsb mov RAX,-020h[RBP] mov byte ptr [RAX],0 ; by default here RAX is null, crash leave ret add [RAX],AL --- I think that the jump is generated here : https://github.com/dlang/dmd/pull/11427/commits/73ee0d06f2e1fb462c2022089266a15591d226ae#diff-db782f03853977be318903ca0db5f79a34511b2b148fdc4d7399cff85f28b358R3929
Comment #4 by bugzilla — 2021-02-03T09:20:49Z
Ah, I see the problem. Line 3932 is in the wrong place.
Comment #5 by dlang-bot — 2021-02-03T09:33:55Z
@WalterBright created dlang/dmd pull request #12177 "fix Issue 21513 - [Reg 2.094.1] Slice assignment segmentation fault" fixing this issue: - fix Issue 21513 - [Reg 2.094.1] Slice assignment segmentation fault https://github.com/dlang/dmd/pull/12177
Comment #6 by dlang-bot — 2021-02-05T06:10:26Z
dlang/dmd pull request #12177 "fix Issue 21513 - [Reg 2.094.1] Slice assignment segmentation fault" was merged into stable: - e716d4dc95ccafe177918ac3a0787f4bd042d60c by Walter Bright: fix Issue 21513 - [Reg 2.094.1] Slice assignment segmentation fault https://github.com/dlang/dmd/pull/12177
Comment #7 by dlang-bot — 2021-02-13T12:29:55Z
dlang/dmd pull request #12195 "Merge stable" was merged into master: - a0047ead2fba821efa8402ab1049b33809b73017 by Walter Bright: fix Issue 21513 - [Reg 2.094.1] Slice assignment segmentation fault https://github.com/dlang/dmd/pull/12195