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

Commit

Permalink
Merge pull request #766 from MartinNowak/fix12580
Browse files Browse the repository at this point in the history
fix Issue 12580 - dup() won't accept void[]
  • Loading branch information
WalterBright committed Apr 17, 2014
2 parents 03d0c15 + 363228b commit 1bd25df
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 14 deletions.
33 changes: 26 additions & 7 deletions src/object.di
Expand Up @@ -629,8 +629,6 @@ version (unittest)
}
}

private extern (C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure nothrow;

/// Provide the .dup array property.
@property auto dup(T)(T[] a)
if (!is(const(T) : T))
Expand Down Expand Up @@ -658,6 +656,13 @@ private extern (C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure no
return _dup!(const(T), T)(a);
}

/// ditto
@property T[] dup(T:void)(const(T)[] a) @trusted
{
if (__ctfe) assert(0, "Cannot dup a void[] array at compile time.");
return cast(T[])_rawDup(a);
}

/// Provide the .idup array property.
@property immutable(T)[] idup(T)(T[] a)
{
Expand All @@ -671,6 +676,12 @@ private extern (C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure no
return _dup!(T, immutable(T))(a);
}

/// ditto
@property immutable(T)[] idup(T:void)(const(T)[] a)
{
return .dup(a);
}

private U[] _trustedDup(T, U)(T[] a) @trusted
{
return _dup!(T, U)(a);
Expand All @@ -686,15 +697,23 @@ private U[] _dup(T, U)(T[] a) // pure nothrow depends on postblit
return res;
}

import core.stdc.string : memcpy;

auto arr = _d_newarrayU(typeid(T[]), a.length);
memcpy(cast(void*)arr.ptr, cast(void*)a.ptr, T.sizeof * a.length);
auto res = *cast(typeof(return)*)&arr;
a = _rawDup(a);
auto res = *cast(typeof(return)*)&a;
_doPostblit(res);
return res;
}

private extern (C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure nothrow;

private inout(T)[] _rawDup(T)(inout(T)[] a)
{
import core.stdc.string : memcpy;

void[] arr = _d_newarrayU(typeid(T[]), a.length);
memcpy(arr.ptr, cast(void*)a.ptr, T.sizeof * a.length);
return *cast(inout(T)[]*)&arr;
}

private void _doPostblit(T)(T[] ary)
{
// infer static postblit type, run postblit if any
Expand Down
52 changes: 45 additions & 7 deletions src/object_.d
Expand Up @@ -2752,8 +2752,6 @@ unittest
assert(aa[[S(12)]] == 13); // fails
}

private extern (C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure nothrow;

public:

/// Provide the .dup array property.
Expand Down Expand Up @@ -2783,6 +2781,13 @@ public:
return _dup!(const(T), T)(a);
}

/// ditto
@property T[] dup(T:void)(const(T)[] a) @trusted
{
if (__ctfe) assert(0, "Cannot dup a void[] array at compile time.");
return cast(T[])_rawDup(a);
}

/// Provide the .idup array property.
@property immutable(T)[] idup(T)(T[] a)
{
Expand All @@ -2796,6 +2801,12 @@ public:
return _dup!(T, immutable(T))(a);
}

/// ditto
@property immutable(T)[] idup(T:void)(const(T)[] a)
{
return .dup(a);
}

private U[] _trustedDup(T, U)(T[] a) @trusted
{
return _dup!(T, U)(a);
Expand All @@ -2811,15 +2822,23 @@ private U[] _dup(T, U)(T[] a) // pure nothrow depends on postblit
return res;
}

import core.stdc.string : memcpy;

auto arr = _d_newarrayU(typeid(T[]), a.length);
memcpy(cast(void*)arr.ptr, cast(void*)a.ptr, T.sizeof * a.length);
auto res = *cast(typeof(return)*)&arr;
a = _rawDup(a);
auto res = *cast(typeof(return)*)&a;
_doPostblit(res);
return res;
}

private extern (C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure nothrow;

private inout(T)[] _rawDup(T)(inout(T)[] a)
{
import core.stdc.string : memcpy;

void[] arr = _d_newarrayU(typeid(T[]), a.length);
memcpy(arr.ptr, cast(void*)a.ptr, T.sizeof * a.length);
return *cast(inout(T)[]*)&arr;
}

private void _doPostblit(T)(T[] ary)
{
// infer static postblit type, run postblit if any
Expand Down Expand Up @@ -2942,3 +2961,22 @@ unittest
auto b = a.dup();
assert(b.capacity >= 3);
}

unittest
{
// Bugzilla 12580
void[] m = [0];
shared(void)[] s = [cast(shared)1];
immutable(void)[] i = [cast(immutable)2];

s.dup();
static assert(is(typeof(s.dup()) == shared(void)[]));

m = i.dup();
i = m.dup();
i = i.idup();
i = m.idup();
i = s.idup();
i = s.dup();
static assert(!__traits(compiles, m = s.dup()));
}

0 comments on commit 1bd25df

Please sign in to comment.