mirror of
https://github.com/openRuyi-Project/gcc.git
synced 2026-09-06 14:01:37 +00:00
D front-end changes: - Import dmd v2.110.0-rc.1. - An error is now given for subtracting pointers of different types. D runtime changes: - Import druntime v2.110.0-rc.1. Phobos changes: - Import phobos v2.110.0-rc.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd c7902293d7. * dmd/VERSION: Bump version to v2.110.0-rc.1. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime c7902293d7. * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Rename core/thread/fiber.d to core/thread/fiber/package.d. Add core/thread/fiber/base.d. * libdruntime/Makefile.in: Regenerate. * src/MERGE: Merge upstream phobos 63fdb282f. gcc/testsuite/ChangeLog: * gdc.dg/asm3.d: Adjust test. * gdc.dg/torture/pr96435.d: Adjust test.
275 lines
6.0 KiB
D
275 lines
6.0 KiB
D
/**
|
|
This module contains support for D's postblit feature
|
|
|
|
Copyright: Copyright Digital Mars 2000 - 2019.
|
|
License: Distributed under the
|
|
$(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
|
|
(See accompanying file LICENSE)
|
|
Source: $(DRUNTIMESRC core/_internal/_postblit.d)
|
|
*/
|
|
module core.internal.postblit;
|
|
|
|
// compiler frontend lowers struct array postblitting to this
|
|
void __ArrayPostblit(T)(T[] a)
|
|
{
|
|
foreach (ref T e; a)
|
|
e.__xpostblit();
|
|
}
|
|
|
|
package void postblitRecurse(S)(ref S s)
|
|
if (is(S == struct))
|
|
{
|
|
static if (__traits(hasMember, S, "__xpostblit") &&
|
|
// Bugzilla 14746: Check that it's the exact member of S.
|
|
__traits(isSame, S, __traits(parent, s.__xpostblit)))
|
|
s.__xpostblit();
|
|
}
|
|
|
|
package void postblitRecurse(E, size_t n)(ref E[n] arr)
|
|
{
|
|
import core.internal.destruction: destructRecurse;
|
|
import core.internal.traits : hasElaborateCopyConstructor;
|
|
|
|
static if (hasElaborateCopyConstructor!E)
|
|
{
|
|
size_t i;
|
|
scope(failure)
|
|
{
|
|
for (; i != 0; --i)
|
|
{
|
|
destructRecurse(arr[i - 1]); // What to do if this throws?
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < arr.length; ++i)
|
|
postblitRecurse(arr[i]);
|
|
}
|
|
}
|
|
|
|
// Test destruction/postblit order
|
|
@safe nothrow pure unittest
|
|
{
|
|
string[] order;
|
|
|
|
struct InnerTop
|
|
{
|
|
~this() @safe nothrow pure
|
|
{
|
|
order ~= "destroy inner top";
|
|
}
|
|
|
|
this(this) @safe nothrow pure
|
|
{
|
|
order ~= "copy inner top";
|
|
}
|
|
}
|
|
|
|
struct InnerMiddle {}
|
|
|
|
version (none) // https://issues.dlang.org/show_bug.cgi?id=14242
|
|
struct InnerElement
|
|
{
|
|
static char counter = '1';
|
|
|
|
~this() @safe nothrow pure
|
|
{
|
|
order ~= "destroy inner element #" ~ counter++;
|
|
}
|
|
|
|
this(this) @safe nothrow pure
|
|
{
|
|
order ~= "copy inner element #" ~ counter++;
|
|
}
|
|
}
|
|
|
|
struct InnerBottom
|
|
{
|
|
~this() @safe nothrow pure
|
|
{
|
|
order ~= "destroy inner bottom";
|
|
}
|
|
|
|
this(this) @safe nothrow pure
|
|
{
|
|
order ~= "copy inner bottom";
|
|
}
|
|
}
|
|
|
|
struct S
|
|
{
|
|
char[] s;
|
|
InnerTop top;
|
|
InnerMiddle middle;
|
|
version (none) InnerElement[3] array; // https://issues.dlang.org/show_bug.cgi?id=14242
|
|
int a;
|
|
InnerBottom bottom;
|
|
~this() @safe nothrow pure { order ~= "destroy outer"; }
|
|
this(this) @safe nothrow pure { order ~= "copy outer"; }
|
|
}
|
|
|
|
string[] destructRecurseOrder;
|
|
{
|
|
import core.internal.destruction: destructRecurse;
|
|
|
|
S s;
|
|
destructRecurse(s);
|
|
destructRecurseOrder = order;
|
|
order = null;
|
|
}
|
|
|
|
assert(order.length);
|
|
assert(destructRecurseOrder == order);
|
|
order = null;
|
|
|
|
S s;
|
|
postblitRecurse(s);
|
|
assert(order.length);
|
|
auto postblitRecurseOrder = order;
|
|
order = null;
|
|
S s2 = s;
|
|
assert(order.length);
|
|
assert(postblitRecurseOrder == order);
|
|
}
|
|
|
|
@safe unittest
|
|
{
|
|
// Bugzilla 14746
|
|
static struct HasPostblit
|
|
{
|
|
this(this) { assert(0); }
|
|
}
|
|
static struct Owner
|
|
{
|
|
HasPostblit* ptr;
|
|
alias ptr this;
|
|
}
|
|
|
|
Owner o;
|
|
assert(o.ptr is null);
|
|
postblitRecurse(o); // must not reach in HasPostblit.__postblit()
|
|
}
|
|
|
|
// Test handling of fixed-length arrays
|
|
// Separate from first test because of https://issues.dlang.org/show_bug.cgi?id=14242
|
|
@safe unittest
|
|
{
|
|
string[] order;
|
|
|
|
struct S
|
|
{
|
|
char id;
|
|
|
|
this(this)
|
|
{
|
|
order ~= "copy #" ~ id;
|
|
}
|
|
|
|
~this()
|
|
{
|
|
order ~= "destroy #" ~ id;
|
|
}
|
|
}
|
|
|
|
string[] destructRecurseOrder;
|
|
{
|
|
import core.internal.destruction: destructRecurse;
|
|
|
|
S[3] arr = [S('1'), S('2'), S('3')];
|
|
destructRecurse(arr);
|
|
destructRecurseOrder = order;
|
|
order = null;
|
|
}
|
|
assert(order.length);
|
|
assert(destructRecurseOrder == order);
|
|
order = null;
|
|
|
|
S[3] arr = [S('1'), S('2'), S('3')];
|
|
postblitRecurse(arr);
|
|
assert(order.length);
|
|
auto postblitRecurseOrder = order;
|
|
order = null;
|
|
|
|
auto arrCopy = arr;
|
|
assert(order.length);
|
|
assert(postblitRecurseOrder == order);
|
|
}
|
|
|
|
// Test handling of failed postblit
|
|
// Not nothrow or @safe because of https://issues.dlang.org/show_bug.cgi?id=14242
|
|
/+ nothrow @safe +/ unittest
|
|
{
|
|
static class FailedPostblitException : Exception { this() nothrow @safe { super(null); } }
|
|
static string[] order;
|
|
static struct Inner
|
|
{
|
|
char id;
|
|
|
|
@safe:
|
|
this(this)
|
|
{
|
|
order ~= "copy inner #" ~ id;
|
|
if (id == '2')
|
|
throw new FailedPostblitException();
|
|
}
|
|
|
|
~this() nothrow
|
|
{
|
|
order ~= "destroy inner #" ~ id;
|
|
}
|
|
}
|
|
|
|
static struct Outer
|
|
{
|
|
Inner inner1, inner2, inner3;
|
|
|
|
nothrow @safe:
|
|
this(char first, char second, char third)
|
|
{
|
|
inner1 = Inner(first);
|
|
inner2 = Inner(second);
|
|
inner3 = Inner(third);
|
|
}
|
|
|
|
this(this)
|
|
{
|
|
order ~= "copy outer";
|
|
}
|
|
|
|
~this()
|
|
{
|
|
order ~= "destroy outer";
|
|
}
|
|
}
|
|
|
|
auto outer = Outer('1', '2', '3');
|
|
|
|
try postblitRecurse(outer);
|
|
catch (FailedPostblitException) {}
|
|
catch (Exception) assert(false);
|
|
|
|
auto postblitRecurseOrder = order;
|
|
order = null;
|
|
|
|
try auto copy = outer;
|
|
catch (FailedPostblitException) {}
|
|
catch (Exception) assert(false);
|
|
|
|
assert(postblitRecurseOrder == order);
|
|
order = null;
|
|
|
|
Outer[3] arr = [Outer('1', '1', '1'), Outer('1', '2', '3'), Outer('3', '3', '3')];
|
|
|
|
try postblitRecurse(arr);
|
|
catch (FailedPostblitException) {}
|
|
catch (Exception) assert(false);
|
|
|
|
postblitRecurseOrder = order;
|
|
order = null;
|
|
|
|
try auto arrCopy = arr;
|
|
catch (FailedPostblitException) {}
|
|
catch (Exception) assert(false);
|
|
|
|
assert(postblitRecurseOrder == order);
|
|
}
|