mirror of
https://github.com/dlang/phobos.git
synced 2025-04-28 06:00:35 +03:00
Merge remote-tracking branch 'origin/stable' into merge_stable
This commit is contained in:
commit
b0ef9ac009
11 changed files with 553 additions and 34 deletions
59
std/array.d
59
std/array.d
|
@ -3639,6 +3639,7 @@ if (isDynamicArray!A)
|
|||
}
|
||||
else
|
||||
{
|
||||
import core.stdc.string : memcpy, memset;
|
||||
// Time to reallocate.
|
||||
// We need to almost duplicate what's in druntime, except we
|
||||
// have better access to the capacity field.
|
||||
|
@ -3650,6 +3651,15 @@ if (isDynamicArray!A)
|
|||
if (u)
|
||||
{
|
||||
// extend worked, update the capacity
|
||||
// if the type has indirections, we need to zero any new
|
||||
// data that we requested, as the existing data may point
|
||||
// at large unused blocks.
|
||||
static if (hasIndirections!T)
|
||||
{
|
||||
immutable addedSize = u - (_data.capacity * T.sizeof);
|
||||
() @trusted { memset(_data.arr.ptr + _data.capacity, 0, addedSize); }();
|
||||
}
|
||||
|
||||
_data.capacity = u / T.sizeof;
|
||||
return;
|
||||
}
|
||||
|
@ -3665,10 +3675,20 @@ if (isDynamicArray!A)
|
|||
|
||||
auto bi = (() @trusted => GC.qalloc(nbytes, blockAttribute!T))();
|
||||
_data.capacity = bi.size / T.sizeof;
|
||||
import core.stdc.string : memcpy;
|
||||
if (len)
|
||||
() @trusted { memcpy(bi.base, _data.arr.ptr, len * T.sizeof); }();
|
||||
|
||||
_data.arr = (() @trusted => (cast(Unqual!T*) bi.base)[0 .. len])();
|
||||
|
||||
// we requested new bytes that are not in the existing
|
||||
// data. If T has pointers, then this new data could point at stale
|
||||
// objects from the last time this block was allocated. Zero that
|
||||
// new data out, it may point at large unused blocks!
|
||||
static if (hasIndirections!T)
|
||||
() @trusted {
|
||||
memset(bi.base + (len * T.sizeof), 0, (newlen - len) * T.sizeof);
|
||||
}();
|
||||
|
||||
_data.tryExtendBlock = true;
|
||||
// leave the old data, for safety reasons
|
||||
}
|
||||
|
@ -4047,6 +4067,43 @@ if (isDynamicArray!A)
|
|||
app2.toString();
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=24856
|
||||
@system unittest
|
||||
{
|
||||
import core.memory : GC;
|
||||
import std.stdio : writeln;
|
||||
import std.algorithm.searching : canFind;
|
||||
GC.disable();
|
||||
scope(exit) GC.enable();
|
||||
void*[] freeme;
|
||||
// generate some poison blocks to allocate from.
|
||||
auto poison = cast(void*) 0xdeadbeef;
|
||||
foreach (i; 0 .. 10)
|
||||
{
|
||||
auto blk = new void*[7];
|
||||
blk[] = poison;
|
||||
freeme ~= blk.ptr;
|
||||
}
|
||||
|
||||
foreach (p; freeme)
|
||||
GC.free(p);
|
||||
|
||||
int tests = 0;
|
||||
foreach (i; 0 .. 10)
|
||||
{
|
||||
Appender!(void*[]) app;
|
||||
app.put(null);
|
||||
// if not a realloc of one of the deadbeef pointers, continue
|
||||
if (!freeme.canFind(app.data.ptr))
|
||||
continue;
|
||||
++tests;
|
||||
assert(!app.data.ptr[0 .. app.capacity].canFind(poison), "Appender not zeroing data!");
|
||||
}
|
||||
// just notify in the log whether this test actually could be done.
|
||||
if (tests == 0)
|
||||
writeln("WARNING: test of Appender zeroing did not occur");
|
||||
}
|
||||
|
||||
//Calculates an efficient growth scheme based on the old capacity
|
||||
//of data, and the minimum requested capacity.
|
||||
//arg curLen: The current length
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue