Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
fix Issue 13661 - static array init does not call destructors
Browse files Browse the repository at this point in the history
Add internal functions to handle assignment from an array with rvalue elements.
  • Loading branch information
9rnsr committed Nov 1, 2014
1 parent 4d82d3d commit c4ec102
Showing 1 changed file with 69 additions and 31 deletions.
100 changes: 69 additions & 31 deletions src/rt/arrayassign.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* Copyright: Copyright Digital Mars 2000 - 2010.
* License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Walter Bright
* Authors: Walter Bright, Kenji Hara
*/

/* Copyright Digital Mars 2000 - 2010.
Expand All @@ -23,54 +23,92 @@ private
}

/**
* Does array assignment (not construction) from another
* array of the same element type.
* ti is the element type.
* Handles overlapping copies.
* Keep for backward binary compatibility. This function can be removed in the future.
*/
extern (C) void[] _d_arrayassign(TypeInfo ti, void[] from, void[] to)
{
debug(PRINTF) printf("_d_arrayassign(from = %p,%d, to = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, ti.tsize);

auto element_size = ti.tsize;

enforceRawArraysConformable("copy", element_size, from, to, true);
immutable elementSize = ti.tsize;

/* Need a temporary buffer tmp[] big enough to hold one element
*/
// Need a temporary buffer tmp[] big enough to hold one element
void[16] buf = void;
void[] tmp;
if (element_size > buf.sizeof)
tmp = alloca(element_size)[0 .. element_size];
else
tmp = buf[];
void* ptmp = (elementSize > buf.sizeof) ? alloca(elementSize) : buf.ptr;
return _d_arrayassign_l(ti, from, to, ptmp);
}

/**
* Does array assignment (not construction) from another
* lvalue array of the same element type.
* Handles overlapping copies.
* Input:
* ti TypeInfo of the element type.
* dst Points target memory. Its .length is equal to the element count, not byte length.
* src Points source memory. Its .length is equal to the element count, not byte length.
* ptmp Temporary memory for element swapping.
*/
extern (C) void[] _d_arrayassign_l(TypeInfo ti, void[] src, void[] dst, void* ptmp)
{
debug(PRINTF) printf("_d_arrayassign_l(src = %p,%d, dst = %p,%d) size = %d\n", src.ptr, src.length, dst.ptr, dst.length, ti.tsize);

immutable elementSize = ti.tsize;

if (to.ptr <= from.ptr)
enforceRawArraysConformable("copy", elementSize, src, dst, true);

if (dst.ptr <= src.ptr)
{
foreach (i; 0 .. to.length)
foreach (i; 0 .. dst.length)
{
void* pto = to.ptr + i * element_size;
void* pfrom = from.ptr + i * element_size;
memcpy(tmp.ptr, pto, element_size);
memcpy(pto, pfrom, element_size);
ti.postblit(pto);
ti.destroy(tmp.ptr);
void* pdst = dst.ptr + i * elementSize;
void* psrc = src.ptr + i * elementSize;
memcpy(ptmp, pdst, elementSize);
memcpy(pdst, psrc, elementSize);
ti.postblit(pdst);
ti.destroy(ptmp);
}
}
else
{
for (auto i = to.length; i--; )
for (auto i = dst.length; i--; )
{
void* pto = to.ptr + i * element_size;
void* pfrom = from.ptr + i * element_size;
memcpy(tmp.ptr, pto, element_size);
memcpy(pto, pfrom, element_size);
ti.postblit(pto);
ti.destroy(tmp.ptr);
void* pdst = dst.ptr + i * elementSize;
void* psrc = src.ptr + i * elementSize;
memcpy(ptmp, pdst, elementSize);
memcpy(pdst, psrc, elementSize);
ti.postblit(pdst);
ti.destroy(ptmp);
}
}
return to;
return dst;
}

/**
* Does array assignment (not construction) from another
* rvalue array of the same element type.
* Input:
* ti TypeInfo of the element type.
* dst Points target memory. Its .length is equal to the element count, not byte length.
* src Points source memory. Its .length is equal to the element count, not byte length.
* It is always allocated on stack and never overlapping with dst.
* ptmp Temporary memory for element swapping.
*/
extern (C) void[] _d_arrayassign_r(TypeInfo ti, void[] src, void[] dst, void* ptmp)
{
debug(PRINTF) printf("_d_arrayassign_r(src = %p,%d, dst = %p,%d) size = %d\n", src.ptr, src.length, dst.ptr, dst.length, ti.tsize);

immutable elementSize = ti.tsize;

enforceRawArraysConformable("copy", elementSize, src, dst, false);

foreach (i; 0 .. dst.length)
{
void* pdst = dst.ptr + i * elementSize;
void* psrc = src.ptr + i * elementSize;
memcpy(ptmp, pdst, elementSize);
memcpy(pdst, psrc, elementSize);
ti.destroy(ptmp);
}
return dst;
}

/**
Expand Down

0 comments on commit c4ec102

Please sign in to comment.