mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-28 17:43:14 +01:00
Call postblit on a struct when appending it to an array. Use _d_arraycatnT to concatenate multiple arrays.
Before, _d_arraycatT was used to concatenate multiple arrays. That caused an issue when postblit
was called on a struct multiple times. The next code asserted due to the issue:
void main()
{
static struct S
{
int x;
int pad;
this(this)
{
++x;
}
}
auto sarr = new S[1];
auto sarr2 = sarr ~ sarr ~ sarr;
assert(sarr2[0].x == 1);
assert(sarr2[1].x == 1);
assert(sarr2[2].x == 1);
assert(sarr[0].x == 0);
}
This commit is contained in:
@@ -47,28 +47,6 @@ void CompoundStatement::toIR(IRState* p)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if DMDV2
|
||||
static void callPostblitHelper(Loc &loc, Expression *exp, LLValue *val)
|
||||
{
|
||||
|
||||
Type *tb = exp->type->toBasetype();
|
||||
if ((exp->op == TOKvar || exp->op == TOKdotvar || exp->op == TOKstar || exp->op == TOKthis) &&
|
||||
tb->ty == Tstruct)
|
||||
{ StructDeclaration *sd = ((TypeStruct *)tb)->sym;
|
||||
if (sd->postblit)
|
||||
{
|
||||
FuncDeclaration *fd = sd->postblit;
|
||||
if (fd->storage_class & STCdisable)
|
||||
fd->toParent()->error(loc, "is not copyable because it is annotated with @disable");
|
||||
fd->codegen(Type::sir);
|
||||
Expressions args;
|
||||
DFuncValue dfn(fd, fd->ir.irFunc->func, val);
|
||||
DtoCallFunction(loc, Type::basic[Tvoid], &dfn, &args);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ReturnStatement::toIR(IRState* p)
|
||||
{
|
||||
Logger::println("ReturnStatement::toIR(): %s", loc.toChars());
|
||||
@@ -101,7 +79,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||
#if DMDV2
|
||||
// call postblit if necessary
|
||||
if (!p->func()->type->isref)
|
||||
callPostblitHelper(loc, exp, rvar->getLVal());
|
||||
callPostblit(loc, exp, rvar->getLVal());
|
||||
#endif
|
||||
|
||||
// emit scopes
|
||||
@@ -127,7 +105,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||
#if DMDV2
|
||||
// call postblit if necessary
|
||||
if (!p->func()->type->isref)
|
||||
callPostblitHelper(loc, exp, dval->getRVal());
|
||||
callPostblit(loc, exp, dval->getRVal());
|
||||
// do abi specific transformations on the return value
|
||||
v = p->func()->type->fty.putRet(exp->type, dval, p->func()->type->isref);
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user