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