Bug 21983 – dup leaves a partially constructed array if postblit/copy ctor throws

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
druntime
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-05-28T15:21:35Z
Last change time
2021-11-02T09:18:59Z
Keywords
pull
Assigned to
No Owner
Creator
moonlightsentinel

Comments

Comment #0 by moonlightsentinel — 2021-05-28T15:21:35Z
dup calls user-defined postblits/copy constructor when creating a new array. But it doesn't destroy the partially constructed array when the postblit/copy constructors throws an exception. The GC will destroy the array (including uninitialized elements!) at an undefined time. dup should destroy the initialized portion of the array and prevent the destruction of uninitialized objects (e.g. by manually freeing the memory).
Comment #1 by moonlightsentinel — 2021-05-28T15:22:51Z
Test case (run with current master): import core.stdc.stdio : puts, printf; struct S { private int id; this(this) { if (id == 2) throw new Exception(""); } ~this() { printf("Destroying %d at %p\n", id, &this); } } void main() { try { S[3] arr = [ S(1), S(2), S(3) ]; arr.dup(); } catch (Exception e) {} puts("Done"); } ==== Destroying 3 at 0x7fffcd3f3888 Destroying 2 at 0x7fffcd3f3884 Destroying 1 at 0x7fffcd3f3880 Done Destroying -968732576 at 0x7fea0ce90008 Destroying 2 at 0x7fea0ce90004 Destroying 1 at 0x7fea0ce90000
Comment #2 by dlang-bot — 2021-05-28T15:29:14Z
@MoonlightSentinel created dlang/druntime pull request #3483 "Fix 21983 - Destroy partially dup'ed array if postblit/copy ctor throws" fixing this issue: - Fix 21983 - Destroy partially dup'ed array if postblit/copy ctor throws This ensures deterministic behaviour in case of an exception and avoids dtor calls on uninitialized elements. https://github.com/dlang/druntime/pull/3483
Comment #3 by razvan.nitu1305 — 2021-11-02T09:18:59Z