Skip to content

Commit

Permalink
more progress on temp destruction
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Mar 27, 2011
1 parent ad2e669 commit e764b39
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 39 deletions.
2 changes: 2 additions & 0 deletions src/backend/cg87.c
Original file line number Diff line number Diff line change
Expand Up @@ -2006,6 +2006,8 @@ code *eq87(elem *e,regm_t *pretregs)
cs.Iflags &= ~CFopsize;
else if (ADDFWAIT())
cs.Iflags |= CFwait;
else if (I64)
cs.Irex &= ~REX_W;
c2 = gen(c2, &cs);
#if LNGDBLSIZE == 12
if (tysize[TYldouble] == 12)
Expand Down
1 change: 1 addition & 0 deletions src/backend/type.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ type *type_fake(tym_t ty)
{ type *t;

#if MARS
if (ty == TYstruct) *(char*)0=0;
assert(ty != TYstruct);
#endif
t = type_alloc(ty);
Expand Down
21 changes: 14 additions & 7 deletions src/declaration.c
Original file line number Diff line number Diff line change
Expand Up @@ -1145,14 +1145,13 @@ void VarDeclaration::semantic(Scope *sc)
if (sd->ctor && // there are constructors
ei->exp->type->ty == Tstruct && // rvalue is the same struct
((TypeStruct *)ei->exp->type)->sym == sd &&
ei->exp->op == TOKstar)
ei->exp->op == TOKcall)
{
/* Look for form of constructor call which is:
* *__ctmp.ctor(arguments...)
*/
PtrExp *pe = (PtrExp *)ei->exp;
if (pe->e1->op == TOKcall)
{ CallExp *ce = (CallExp *)pe->e1;
if (1)
{ CallExp *ce = (CallExp *)ei->exp;
if (ce->e1->op == TOKdotvar)
{ DotVarExp *dve = (DotVarExp *)ce->e1;
if (dve->var->isCtorDeclaration())
Expand All @@ -1163,15 +1162,23 @@ void VarDeclaration::semantic(Scope *sc)
* variable with a bit copy of the default
* initializer
*/
Expression *e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc));
e->op = TOKblit;
Expression *e;
if (sd->zeroInit == 1)
{
e = new ConstructExp(loc, new VarExp(loc, this), new IntegerExp(loc, 0, Type::tint32));
}
else
{ e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc));
e->op = TOKblit;
}
e->type = t;
ei->exp = new CommaExp(loc, e, ei->exp);

/* Replace __ctmp being constructed with e1
*/
dve->e1 = e1;
return;
ei->exp = ei->exp->semantic(sc);
goto Ldtor;
}
}
}
Expand Down
65 changes: 41 additions & 24 deletions src/e2ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,21 @@ elem *Expression::toElem(IRState *irs)
return NULL;
}

/*******************************************
* Evaluate Expression, then call destructors on any temporaries in it.
*/

elem *Expression::toElemDtor(IRState *irs)
{
size_t starti = irs->varsInScope ? irs->varsInScope->dim : 0;
elem *er = toElem(irs);
size_t endi = irs->varsInScope ? irs->varsInScope->dim : 0;

// Add destructors
er = appendDtors(irs, er, starti, endi);
return er;
}

/************************************
*/
#if DMDV2
Expand Down Expand Up @@ -3221,14 +3236,7 @@ elem *AndAndExp::toElem(IRState *irs)
tym_t tym = type->totym();

elem *el = e1->toElem(irs);

size_t starti = irs->varsInScope ? irs->varsInScope->dim : 0;
elem *er = e2->toElem(irs);
size_t endi = irs->varsInScope ? irs->varsInScope->dim : 0;

// Add destructors for e2
er = appendDtors(irs, er, starti, endi);

elem *er = e2->toElemDtor(irs);
elem *e = el_bin(OPandand,tym,el,er);

el_setLoc(e,loc);
Expand All @@ -3247,14 +3255,7 @@ elem *OrOrExp::toElem(IRState *irs)
tym_t tym = type->totym();

elem *el = e1->toElem(irs);

size_t starti = irs->varsInScope ? irs->varsInScope->dim : 0;
elem *er = e2->toElem(irs);
size_t endi = irs->varsInScope ? irs->varsInScope->dim : 0;

// Add destructors for e2
er = appendDtors(irs, er, starti, endi);

elem *er = e2->toElemDtor(irs);
elem *e = el_bin(OPoror,tym,el,er);

el_setLoc(e,loc);
Expand Down Expand Up @@ -3343,17 +3344,15 @@ elem *CommaExp::toElem(IRState *irs)
*/

elem *CondExp::toElem(IRState *irs)
{ elem *eleft;
elem *eright;

{
elem *ec = econd->toElem(irs);

eleft = e1->toElem(irs);
elem *eleft = e1->toElemDtor(irs);
tym_t ty = eleft->Ety;
if (global.params.cov && e1->loc.linnum)
eleft = el_combine(incUsageElem(irs, e1->loc), eleft);

eright = e2->toElem(irs);
elem *eright = e2->toElemDtor(irs);
if (global.params.cov && e2->loc.linnum)
eright = el_combine(incUsageElem(irs, e2->loc), eright);

Expand Down Expand Up @@ -5127,9 +5126,27 @@ elem *appendDtors(IRState *irs, elem *er, size_t starti, size_t endi)
}
if (edtors)
{
elem *e = el_same(&er);
er = el_combine(er, edtors);
er = el_combine(er, e);
if (tybasic(er->Ety) == TYvoid)
{
er = el_combine(er, edtors);
}
else if (tybasic(er->Ety) == TYstruct || tybasic(er->Ety) == TYarray)
{
elem *ep = el_una(OPaddr, TYnptr, er);
elem *e = el_same(&ep);
ep = el_combine(ep, edtors);
ep = el_combine(ep, e);
e = el_una(OPind, er->Ety, ep);
e->ET = er->ET;
er = e;
}
else
{
elem *e = el_same(&er);
er = el_combine(er, edtors);
er = el_combine(er, e);
}
}
return er;
}

58 changes: 52 additions & 6 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ void preFunctionParameters(Loc loc, Scope *sc, Expressions *exps)
* Call copy constructor for struct value argument.
*/
#if DMDV2
Expression *callCpCtor(Loc loc, Scope *sc, Expression *e)
Expression *callCpCtor(Loc loc, Scope *sc, Expression *e, int noscope)
{
Type *tb = e->type->toBasetype();
assert(tb->ty == Tstruct);
Expand All @@ -477,9 +477,10 @@ Expression *callCpCtor(Loc loc, Scope *sc, Expression *e)
* This is not the most efficent, ideally tmp would be constructed
* directly onto the stack.
*/
Identifier *idtmp = Lexer::uniqueId("__tmp");
Identifier *idtmp = Lexer::uniqueId("__cpcttmp");
VarDeclaration *tmp = new VarDeclaration(loc, tb, idtmp, new ExpInitializer(0, e));
tmp->storage_class |= STCctfe;
tmp->noscope = noscope;
Expression *ae = new DeclarationExp(loc, tmp);
e = new CommaExp(loc, ae, new VarExp(loc, tmp));
e = e->semantic(sc);
Expand Down Expand Up @@ -680,10 +681,41 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
#if DMDV2
if (tb->ty == Tstruct && !(p->storageClass & (STCref | STCout)))
{
arg = callCpCtor(loc, sc, arg);
if (arg->op == TOKcall)
{
/* The struct value returned from the function is transferred
* to the function, so the callee should not call the destructor
* on it.
* ((S _ctmp = S.init), _ctmp).this(...)
*/
CallExp *ce = (CallExp *)arg;
if (ce->e1->op == TOKdotvar)
{ DotVarExp *dve = (DotVarExp *)ce->e1;
if (dve->var->isCtorDeclaration())
{ // It's a constructor call
if (dve->e1->op == TOKcomma)
{ CommaExp *comma = (CommaExp *)dve->e1;
if (comma->e2->op == TOKvar)
{ VarExp *ve = (VarExp *)comma->e2;
VarDeclaration *ctmp = ve->var->isVarDeclaration();
if (ctmp)
ctmp->noscope = 1;
}
}
}
}
}
else
{ /* Not transferring it, so call the copy constructor
*/
arg = callCpCtor(loc, sc, arg, 1);
}
}
#endif

//printf("arg: %s\n", arg->toChars());
//printf("type: %s\n", arg->type->toChars());

// Convert lazy argument to a delegate
if (p->storageClass & STClazy)
{
Expand Down Expand Up @@ -761,7 +793,7 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
#if DMDV2
if (tb->ty == Tstruct)
{
arg = callCpCtor(loc, sc, arg);
arg = callCpCtor(loc, sc, arg, 1);
}
#endif

Expand Down Expand Up @@ -8851,7 +8883,7 @@ Expression *PostExp::semantic(Scope *sc)
/* Rewrite as:
* auto tmp = e1; ++e1; tmp
*/
Identifier *id = Lexer::uniqueId("__tmp");
Identifier *id = Lexer::uniqueId("__pitmp");
ExpInitializer *ei = new ExpInitializer(loc, e1);
VarDeclaration *tmp = new VarDeclaration(loc, e1->type, id, ei);
Expression *ea = new DeclarationExp(loc, tmp);
Expand Down Expand Up @@ -9137,6 +9169,16 @@ Expression *AssignExp::semantic(Scope *sc)
sd->cpctor)
{ /* We have a copy constructor for this
*/
// Scan past commma's
Expression *ec = NULL;
while (e2->op == TOKcomma)
{ CommaExp *ecomma = (CommaExp *)e2;
e2 = ecomma->e2;
if (ec)
ec = new CommaExp(ecomma->loc, ec, ecomma->e1);
else
ec = ecomma->e1;
}
if (e2->op == TOKquestion)
{ /* Write as:
* a ? e1 = b : e1 = c;
Expand All @@ -9147,6 +9189,8 @@ Expression *AssignExp::semantic(Scope *sc)
AssignExp *ea2 = new AssignExp(ec->e1->loc, e1, ec->e2);
ea2->op = op;
Expression *e = new CondExp(loc, ec->econd, ea1, ea2);
if (ec)
e = new CommaExp(loc, ec, e);
return e->semantic(sc);
}
else if (e2->op == TOKvar ||
Expand All @@ -9159,6 +9203,8 @@ Expression *AssignExp::semantic(Scope *sc)
*/
Expression *e = new DotVarExp(loc, e1, sd->cpctor, 0);
e = new CallExp(loc, e, e2);
if (ec)
e = new CommaExp(loc, ec, e);
return e->semantic(sc);
}
}
Expand Down Expand Up @@ -10405,7 +10451,7 @@ Expression *PowExp::semantic(Scope *sc)
typeCombine(sc);
// Replace x^^2 with (tmp = x, tmp*tmp)
// Replace x^^3 with (tmp = x, tmp*tmp*tmp)
Identifier *idtmp = Lexer::uniqueId("__tmp");
Identifier *idtmp = Lexer::uniqueId("__powtmp");
VarDeclaration *tmp = new VarDeclaration(loc, e1->type->toBasetype(), idtmp, new ExpInitializer(0, e1));
tmp->storage_class = STCctfe;
Expression *ve = new VarExp(loc, tmp);
Expand Down
1 change: 1 addition & 0 deletions src/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ struct Expression : Object

// Back end
virtual elem *toElem(IRState *irs);
elem *toElemDtor(IRState *irs);
virtual dt_t **toDt(dt_t **pdt);
};

Expand Down
5 changes: 4 additions & 1 deletion src/inline.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

// Copyright (c) 1999-2010 by Digital Mars
// Copyright (c) 1999-2011 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
Expand Down Expand Up @@ -240,6 +240,9 @@ int DeclarationExp::inlineCost(InlineCostState *ics)
return COST_MAX;
cost += 1;

if (vd->edtor) // if destructor required
return COST_MAX; // needs work to make this work

// Scan initializer (vd->init)
if (vd->init)
{
Expand Down
2 changes: 1 addition & 1 deletion src/s2ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1307,7 +1307,7 @@ void ExpStatement::toIR(IRState *irs)
//printf("ExpStatement::toIR(), exp = %s\n", exp ? exp->toChars() : "");
incUsage(irs, loc);
if (exp)
block_appendexp(blx->curblock,exp->toElem(irs));
block_appendexp(blx->curblock,exp->toElemDtor(irs));
}

/**************************************
Expand Down

2 comments on commit e764b39

@shoo
Copy link
Contributor

@shoo shoo commented on e764b39 Apr 1, 2011

Choose a reason for hiding this comment

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

I tested this problem and find remaining bug at commit 52dd808
Detail is here: http://d.puremagic.com/issues/show_bug.cgi?id=5657

@CyberShadow
Copy link
Member

Choose a reason for hiding this comment

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

This commit introduced a regression:
https://issues.dlang.org/show_bug.cgi?id=17246

Please sign in to comment.