Skip to content

Commit

Permalink
same same for postblit
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinNowak committed May 15, 2015
1 parent c42dbb9 commit a6b73d2
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 15 deletions.
26 changes: 19 additions & 7 deletions src/clone.c
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"));
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
2 changes: 1 addition & 1 deletion src/func.c
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
6 changes: 4 additions & 2 deletions src/idgen.d
Expand Up @@ -42,7 +42,10 @@ Msgtable[] msgtable =
{ "__xdtor", "__xdtor" },
{ "__fieldDtor", "__fieldDtor" },
{ "__aggrDtor", "__aggrDtor" },
{ "_postblit", "__postblit" },
{ "postblit", "__postblit" },
{ "__xpostblit", "__xpostblit" },
{ "__fieldPostblit", "__fieldPostblit" },
{ "__aggrPostblit", "__aggrPostblit" },
{ "classInvariant", "__invariant" },
{ "unitTest", "__unitTest" },
{ "require", "__require" },
Expand Down Expand Up @@ -107,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
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
3 changes: 2 additions & 1 deletion src/traits.c
Expand Up @@ -977,7 +977,8 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
sm->ident != Id::ctor &&
sm->ident != Id::dtor &&
sm->ident != Id::__xdtor &&
sm->ident != Id::_postblit)
sm->ident != Id::postblit &&
sm->ident != Id::__xpostblit)
{
return 0;
}
Expand Down
3 changes: 1 addition & 2 deletions test/fail_compilation/fail4421.d
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;
}
}

2 changes: 1 addition & 1 deletion test/runnable/traits.d
Expand Up @@ -1254,7 +1254,7 @@ struct S10096X
}
static assert(
[__traits(allMembers, S10096X)] ==
["str", "__ctor", "__postblit", "__dtor", "__xdtor", "opAssign"]);
["str", "__ctor", "__postblit", "__dtor", "__xdtor", "__xpostblit", "opAssign"]);

// --------

Expand Down
77 changes: 77 additions & 0 deletions test/runnable/xpostblit.d
@@ -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();
}

0 comments on commit a6b73d2

Please sign in to comment.