Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 36 additions & 12 deletions src/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -833,13 +833,13 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
ea = new CastExp(loc, ea, Type::tvoid->pointerTo());

Expression *et = getTypeInfo(v->type, sc);
et = new DotIdExp(loc, et, Id::postblit);
et = new DotIdExp(loc, et, Identifier::idPool("postblit"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh? This is the reverse of other changes further down.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, but I can only have one Id::postblit, and for the sake of consistency I made Id::postblit like Id::ctor to mean the native mangling.

ex = new CallExp(loc, et, ea);
}
a->push(new ExpStatement(loc, ex)); // combine in forward order

/* Bugzilla 10972: When the following field postblit calls fail,
* this field should be destructed for Excetion Safety.
* this field should be destructed for Exception Safety.
*/
if (!sdv->dtor)
continue;
Expand Down Expand Up @@ -869,20 +869,22 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
if (a || (stc & STCdisable))
{
//printf("Building __fieldPostBlit()\n");
PostBlitDeclaration *dd = new PostBlitDeclaration(declLoc, Loc(), stc, Identifier::idPool("__fieldPostBlit"));
PostBlitDeclaration *dd = new PostBlitDeclaration(declLoc, Loc(), stc, Id::__fieldPostblit);
dd->fbody = a ? new CompoundStatement(loc, a) : NULL;
sd->postblits.shift(dd);
sd->members->push(dd);
dd->semantic(sc);
}

FuncDeclaration *xpostblit = NULL;
switch (sd->postblits.dim)
{
case 0:
return NULL;
break;

case 1:
return sd->postblits[0];
xpostblit = sd->postblits[0];
break;

default:
Expression *e = NULL;
Expand All @@ -901,12 +903,22 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
ex = new CallExp(loc, ex);
e = Expression::combine(e, ex);
}
PostBlitDeclaration *dd = new PostBlitDeclaration(declLoc, Loc(), stc, Identifier::idPool("__aggrPostBlit"));
PostBlitDeclaration *dd = new PostBlitDeclaration(declLoc, Loc(), stc, Id::__aggrPostblit);
dd->fbody = new ExpStatement(loc, e);
sd->members->push(dd);
dd->semantic(sc);
return dd;
xpostblit = dd;
break;
}
// Add an __xpostblit alias to make the inclusive postblit accessible
if (xpostblit)
{
AliasDeclaration *alias = new AliasDeclaration(Loc(), Id::__xpostblit, xpostblit);
alias->semantic(sc);
sd->members->push(alias);
alias->addMember(sc, sd); // add to symbol table
}
return xpostblit;
}

/*****************************************
Expand Down Expand Up @@ -969,20 +981,22 @@ FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc)
if (e || (stc & STCdisable))
{
//printf("Building __fieldDtor()\n");
DtorDeclaration *dd = new DtorDeclaration(declLoc, Loc(), stc, Identifier::idPool("__fieldDtor"));
DtorDeclaration *dd = new DtorDeclaration(declLoc, Loc(), stc, Id::__fieldDtor);
dd->fbody = new ExpStatement(loc, e);
ad->dtors.shift(dd);
ad->members->push(dd);
dd->semantic(sc);
}

FuncDeclaration *xdtor = NULL;
switch (ad->dtors.dim)
{
case 0:
return NULL;
break;

case 1:
return ad->dtors[0];
xdtor = ad->dtors[0];
break;

default:
e = NULL;
Expand All @@ -1001,12 +1015,22 @@ FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc)
ex = new CallExp(loc, ex);
e = Expression::combine(ex, e);
}
DtorDeclaration *dd = new DtorDeclaration(declLoc, Loc(), stc, Identifier::idPool("__aggrDtor"));
DtorDeclaration *dd = new DtorDeclaration(declLoc, Loc(), stc, Id::__aggrDtor);
dd->fbody = new ExpStatement(loc, e);
ad->members->push(dd);
dd->semantic(sc);
return dd;
xdtor = dd;
break;
}
// Add an __xdtor alias to make the inclusive dtor accessible
if (xdtor)
{
AliasDeclaration *alias = new AliasDeclaration(Loc(), Id::__xdtor, xdtor);
alias->semantic(sc);
ad->members->push(alias);
alias->addMember(sc, ad); // add to symbol table
}
return xdtor;
}

/******************************************
Expand Down
2 changes: 1 addition & 1 deletion src/func.c
Original file line number Diff line number Diff line change
Expand Up @@ -4691,7 +4691,7 @@ void PostBlitDeclaration::semantic(Scope *sc)
errors = true;
return;
}
if (ident == Id::_postblit && semanticRun < PASSsemantic)
if (ident == Id::postblit && semanticRun < PASSsemantic)
ad->postblits.push(this);
if (!type)
type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
Expand Down
9 changes: 7 additions & 2 deletions src/idgen.d
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ Msgtable[] msgtable =
{ "super" },
{ "ctor", "__ctor" },
{ "dtor", "__dtor" },
{ "_postblit", "__postblit" },
{ "__xdtor", "__xdtor" },
{ "__fieldDtor", "__fieldDtor" },
{ "__aggrDtor", "__aggrDtor" },
{ "postblit", "__postblit" },
{ "__xpostblit", "__xpostblit" },
{ "__fieldPostblit", "__fieldPostblit" },
{ "__aggrPostblit", "__aggrPostblit" },
{ "classInvariant", "__invariant" },
{ "unitTest", "__unitTest" },
{ "require", "__require" },
Expand Down Expand Up @@ -104,7 +110,6 @@ Msgtable[] msgtable =
{ "_arguments" },
{ "_argptr" },
{ "destroy" },
{ "postblit" },
{ "xopEquals", "__xopEquals" },
{ "xopCmp", "__xopCmp" },
{ "xtoHash", "__xtoHash" },
Expand Down
2 changes: 1 addition & 1 deletion src/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1470,7 +1470,7 @@ Dsymbol *Parser::parseCtor(PrefixAttributes *pAttrs)
if (stc & STCstatic)
error(loc, "postblit cannot be static");

PostBlitDeclaration *f = new PostBlitDeclaration(loc, Loc(), stc, Id::_postblit);
PostBlitDeclaration *f = new PostBlitDeclaration(loc, Loc(), stc, Id::postblit);
if (pAttrs)
pAttrs->storageClass = STCundefined;
Dsymbol *s = parseContracts(f);
Expand Down
8 changes: 5 additions & 3 deletions src/traits.c
Original file line number Diff line number Diff line change
Expand Up @@ -973,10 +973,12 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
//printf("\t[%i] %s %s\n", i, sm->kind(), sm->toChars());
if (sm->ident)
{
if (sm->ident != Id::ctor &&
if (sm->ident->string[0] == '_' && sm->ident->string[1] == '_' &&
sm->ident != Id::ctor &&
sm->ident != Id::dtor &&
sm->ident != Id::_postblit &&
memcmp(sm->ident->string, "__", 2) == 0)
sm->ident != Id::__xdtor &&
sm->ident != Id::postblit &&
sm->ident != Id::__xpostblit)
{
return 0;
}
Expand Down
4 changes: 4 additions & 0 deletions test/compilable/extra-files/json.out
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@
"overrides" : [
"json.Baz!(int, 2, null).Baz.t"
]
},
{
"name" : "__xdtor",
"kind" : "alias"
}
]
},
Expand Down
3 changes: 1 addition & 2 deletions test/fail_compilation/fail4421.d
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ fail_compilation/fail4421.d(17): Error: destructor fail4421.U1.~this destructors
fail_compilation/fail4421.d(18): Error: function fail4421.U1.__invariant1 destructors, postblits and invariants are not allowed in union U1
fail_compilation/fail4421.d(14): Error: function fail4421.U1.__invariant destructors, postblits and invariants are not allowed in union U1
fail_compilation/fail4421.d(28): Error: destructor fail4421.U2.~this destructors, postblits and invariants are not allowed in union U2
fail_compilation/fail4421.d(28): Error: function fail4421.U2.__fieldPostBlit destructors, postblits and invariants are not allowed in union U2
fail_compilation/fail4421.d(28): Error: function fail4421.U2.__fieldPostblit destructors, postblits and invariants are not allowed in union U2
fail_compilation/fail4421.d(33): Error: struct fail4421.S2 destructors, postblits and invariants are not allowed in overlapping fields s1 and j
---
*/
Expand Down Expand Up @@ -38,4 +38,3 @@ struct S2
int j;
}
}

4 changes: 2 additions & 2 deletions test/runnable/traits.d
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ void test14()
{
auto a = [__traits(derivedMembers, D14)];
writeln(a);
assert(a == ["__ctor","__dtor","foo"]);
assert(a == ["__ctor","__dtor","foo", "__xdtor"]);
}

/********************************************************/
Expand Down Expand Up @@ -1254,7 +1254,7 @@ struct S10096X
}
static assert(
[__traits(allMembers, S10096X)] ==
["str", "__ctor", "__postblit", "__dtor", "opAssign"]);
["str", "__ctor", "__postblit", "__dtor", "__xdtor", "__xpostblit", "opAssign"]);

// --------

Expand Down
86 changes: 86 additions & 0 deletions test/runnable/xdtor.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// PERMUTE_ARGS:

struct Field
{
~this() @safe @nogc pure nothrow {}
}

struct Counter
{
static size_t cnt;
~this() @safe @nogc nothrow { ++cnt; }
}

struct Foo
{
~this() @safe @nogc pure nothrow {}
Field field;
}

class Bar
{
~this() @safe @nogc pure nothrow {}
Field field;
}

void test1() @safe @nogc pure nothrow
{
Foo foo;
foo.__xdtor();
scope bar = new Bar();
bar.__xdtor();
}

static assert(__traits(hasMember, Foo, "__xdtor"));
static assert(__traits(hasMember, Bar, "__xdtor"));

//

struct FieldDtor
{
Counter counter;
}

struct AggrDtor
{
static size_t cnt;
~this() @safe @nogc nothrow { ++cnt; }
}

struct MixedDtor
{
static size_t cnt;
Counter counter;
~this() @safe @nogc nothrow { ++cnt; }
}

struct SNoDtor {}
class CNoDtor {}

static assert(!__traits(hasMember, SNoDtor, "__xdtor"));
static assert(!__traits(hasMember, CNoDtor, "__xdtor"));

void test2() @safe @nogc nothrow
{
FieldDtor a;
assert(Counter.cnt == 0);
a.__xdtor();
assert(Counter.cnt == 1);
AggrDtor b;
assert(AggrDtor.cnt == 0);
b.__xdtor();
assert(AggrDtor.cnt == 1);
Counter.cnt = 0;
MixedDtor c;
assert(MixedDtor.cnt == 0);
assert(Counter.cnt == 0);
c.__xdtor();
assert(MixedDtor.cnt == 1);
assert(Counter.cnt == 1);
}

void main()
{
test1();
test2();
}
77 changes: 77 additions & 0 deletions test/runnable/xpostblit.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// PERMUTE_ARGS:

struct Field
{
this(this) @safe @nogc pure nothrow {}
}

struct Counter
{
static size_t cnt;
this(this) @safe @nogc nothrow { ++cnt; }
}

struct Foo
{
this(this) @safe @nogc pure nothrow {}
Field field;
}

void test1() @safe @nogc pure nothrow
{
Foo foo;
foo.__xpostblit();
}

static assert(__traits(hasMember, Foo, "__xpostblit"));

//

struct FieldPostblit
{
Counter counter;
}

struct AggrPostblit
{
static size_t cnt;
this(this) @safe @nogc nothrow { ++cnt; }
}

struct MixedPostblit
{
static size_t cnt;
Counter counter;
this(this) @safe @nogc nothrow { ++cnt; }
}

struct SNoPostblit {}
class CNoPostblit {}

static assert(!__traits(hasMember, SNoPostblit, "__xpostblit"));
static assert(!__traits(hasMember, CNoPostblit, "__xpostblit"));

void test2() @safe @nogc nothrow
{
FieldPostblit a;
assert(Counter.cnt == 0);
a.__xpostblit();
assert(Counter.cnt == 1);
AggrPostblit b;
assert(AggrPostblit.cnt == 0);
b.__xpostblit();
assert(AggrPostblit.cnt == 1);
Counter.cnt = 0;
MixedPostblit c;
assert(MixedPostblit.cnt == 0);
assert(Counter.cnt == 0);
c.__xpostblit();
assert(MixedPostblit.cnt == 1);
assert(Counter.cnt == 1);
}

void main()
{
test1();
test2();
}