From a6b73d22203ccac50681c7b5b581da81976441ff Mon Sep 17 00:00:00 2001 From: Martin Nowak Date: Fri, 15 May 2015 03:02:01 +0200 Subject: [PATCH] same same for postblit --- src/clone.c | 26 ++++++++--- src/func.c | 2 +- src/idgen.d | 6 ++- src/parse.c | 2 +- src/traits.c | 3 +- test/fail_compilation/fail4421.d | 3 +- test/runnable/traits.d | 2 +- test/runnable/xpostblit.d | 77 ++++++++++++++++++++++++++++++++ 8 files changed, 106 insertions(+), 15 deletions(-) create mode 100644 test/runnable/xpostblit.d diff --git a/src/clone.c b/src/clone.c index 9e6241250969..e48595c9fcb9 100644 --- a/src/clone.c +++ b/src/clone.c @@ -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; @@ -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; @@ -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; } /***************************************** diff --git a/src/func.c b/src/func.c index 196afc978d3e..78021f59a2b7 100644 --- a/src/func.c +++ b/src/func.c @@ -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); diff --git a/src/idgen.d b/src/idgen.d index 6b3e128888b6..a16977503f7a 100644 --- a/src/idgen.d +++ b/src/idgen.d @@ -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" }, @@ -107,7 +110,6 @@ Msgtable[] msgtable = { "_arguments" }, { "_argptr" }, { "destroy" }, - { "postblit" }, { "xopEquals", "__xopEquals" }, { "xopCmp", "__xopCmp" }, { "xtoHash", "__xtoHash" }, diff --git a/src/parse.c b/src/parse.c index e04a7904f8c9..3f476f4901a3 100644 --- a/src/parse.c +++ b/src/parse.c @@ -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); diff --git a/src/traits.c b/src/traits.c index 4ca3a4972fde..cf6ecd9abaa7 100644 --- a/src/traits.c +++ b/src/traits.c @@ -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; } diff --git a/test/fail_compilation/fail4421.d b/test/fail_compilation/fail4421.d index a691ab6b535f..1cd4961af47c 100644 --- a/test/fail_compilation/fail4421.d +++ b/test/fail_compilation/fail4421.d @@ -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 --- */ @@ -38,4 +38,3 @@ struct S2 int j; } } - diff --git a/test/runnable/traits.d b/test/runnable/traits.d index 7ed6ab834167..7e69371d2c0b 100644 --- a/test/runnable/traits.d +++ b/test/runnable/traits.d @@ -1254,7 +1254,7 @@ struct S10096X } static assert( [__traits(allMembers, S10096X)] == - ["str", "__ctor", "__postblit", "__dtor", "__xdtor", "opAssign"]); + ["str", "__ctor", "__postblit", "__dtor", "__xdtor", "__xpostblit", "opAssign"]); // -------- diff --git a/test/runnable/xpostblit.d b/test/runnable/xpostblit.d new file mode 100644 index 000000000000..b364c4cff63a --- /dev/null +++ b/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(); +}