Skip to content

Commit

Permalink
Merge pull request #4078 from WalterBright/fix13586
Browse files Browse the repository at this point in the history
fix Issue 13586 - Destructors not run when argument list evaluation throws
  • Loading branch information
9rnsr committed Oct 26, 2014
2 parents c6289aa + aea25d6 commit 11276b8
Show file tree
Hide file tree
Showing 11 changed files with 297 additions and 29 deletions.
6 changes: 6 additions & 0 deletions src/backend/cod2.c
Expand Up @@ -5108,6 +5108,12 @@ code *cdddtor(elem *e,regm_t *pretregs)
cd = cat(cd, nteh_gensindex(0)); // the actual index will be patched in later
// by except_fillInEHTable()

// Mark all registers as destroyed
{
code *cy = getregs(allregs);
assert(!cy);
}

assert(*pretregs == 0);
code *c = codelem(e->E1,pretregs,FALSE);
gen1(c,0xC3); // RET
Expand Down
5 changes: 4 additions & 1 deletion src/backend/cod3.c
Expand Up @@ -1416,6 +1416,8 @@ void doswitch(block *b)
gen2sib(ce,LEA,(REX_W << 16) | modregxrm(0,r1,4),modregxrmx(0,r1,r2)); // LEA R1,[R1][R2]
gen2(ce,0xFF,modregrmx(3,4,r1)); // JMP R1

pinholeopt(ce, NULL);

b->Btablesize = (int) (vmax - vmin + 1) * 4;
}
else
Expand Down Expand Up @@ -5243,7 +5245,8 @@ void pinholeopt(code *c,block *b)
}

// Replace [R13] with 0[R13]
if (c->Irex & REX_B && (c->Irm & modregrm(3,0,5)) == modregrm(0,0,5))
if (c->Irex & REX_B && ((c->Irm & modregrm(3,0,7)) == modregrm(0,0,BP) ||
issib(c->Irm) && (c->Irm & modregrm(3,0,0)) == 0 && (c->Isib & 7) == BP))
{
c->Irm |= modregrm(1,0,0);
c->IFL1 = FLconst;
Expand Down
1 change: 1 addition & 0 deletions src/backend/gdag.c
Expand Up @@ -258,6 +258,7 @@ STATIC void aewalk(register elem **pn,register vec_t ae)
case OPdctor:
break;
case OPasm:
case OPddtor:
vec_clear(ae); // kill everything
return;

Expand Down
1 change: 1 addition & 0 deletions src/backend/gflow.c
Expand Up @@ -974,6 +974,7 @@ STATIC void accumaecpx(elem *n)
vec_free(Kr);
break;
}
case OPddtor:
case OPasm:
assert(!n->Eexp); // no ASM available expressions
vec_set(KILL); // KILL everything
Expand Down
3 changes: 2 additions & 1 deletion src/declaration.h
Expand Up @@ -83,7 +83,8 @@ enum PURE;
#define STCnodefaultctor 0x8000000000LL // must be set inside constructor
#define STCtemp 0x10000000000LL // temporary variable
#define STCrvalue 0x20000000000LL // force rvalue for variables
#define STCnogc 0x40000000000LL // @nogc
#define STCnogc 0x40000000000LL // @nogc
#define STCvolatile 0x80000000000LL // destined for volatile in the back end

const StorageClass STCStorageClass = (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal |
STCabstract | STCsynchronized | STCdeprecated | STCoverride | STClazy | STCalias |
Expand Down
15 changes: 15 additions & 0 deletions src/e2ir.c
Expand Up @@ -1383,6 +1383,7 @@ elem *toElem(Expression *e, IRState *irs)

elem *ex = NULL;
elem *ey = NULL;
elem *ezprefix = NULL;
elem *ez = NULL;

if (ne->allocator || ne->onstack)
Expand Down Expand Up @@ -1489,11 +1490,14 @@ elem *toElem(Expression *e, IRState *irs)

if (ne->member)
{
if (ne->argprefix)
ezprefix = toElem(ne->argprefix, irs);
// Call constructor
ez = callfunc(ne->loc, irs, 1, ne->type, ez, ectype, ne->member, ne->member->type, NULL, ne->arguments);
}

e = el_combine(ex, ey);
e = el_combine(e, ezprefix);
e = el_combine(e, ez);
}
else if (t->ty == Tpointer && t->nextOf()->toBasetype()->ty == Tstruct)
Expand All @@ -1511,6 +1515,7 @@ elem *toElem(Expression *e, IRState *irs)

elem *ex = NULL;
elem *ey = NULL;
elem *ezprefix = NULL;
elem *ez = NULL;

if (ne->allocator)
Expand All @@ -1537,6 +1542,8 @@ elem *toElem(Expression *e, IRState *irs)

elem *ev = el_same(&ex);

if (ne->argprefix)
ezprefix = toElem(ne->argprefix, irs);
if (ne->member)
{
if (sd->isNested())
Expand Down Expand Up @@ -1579,12 +1586,15 @@ elem *toElem(Expression *e, IRState *irs)
//elem_print(ez);

e = el_combine(ex, ey);
e = el_combine(e, ezprefix);
e = el_combine(e, ez);
}
else if (t->ty == Tarray)
{
TypeDArray *tda = (TypeDArray *)t;

elem *ezprefix = ne->argprefix ? toElem(ne->argprefix, irs) : NULL;

assert(ne->arguments && ne->arguments->dim >= 1);
if (ne->arguments->dim == 1)
{
Expand Down Expand Up @@ -1616,11 +1626,13 @@ elem *toElem(Expression *e, IRState *irs)
e = el_bin(OPcall,TYdarray,el_var(rtlsym[rtl]),e);
e->Eflags |= EFLAGS_variadic;
}
e = el_combine(ezprefix, e);
}
else if (t->ty == Tpointer)
{
TypePointer *tp = (TypePointer *)t;
Expression *di = tp->next->defaultInit();
elem *ezprefix = ne->argprefix ? toElem(ne->argprefix, irs) : NULL;

// call _d_newitemT(ti)
e = toElem(ne->newtype->getTypeInfo(NULL), irs);
Expand All @@ -1630,6 +1642,8 @@ elem *toElem(Expression *e, IRState *irs)

if (ne->arguments && ne->arguments->dim == 1)
{
/* ezprefix, ts=_d_newitemT(ti), *ts=arguments[0], ts
*/
elem *e2 = toElem((*ne->arguments)[0], irs);

symbol *ts = symbol_genauto(Type_toCtype(tp));
Expand All @@ -1642,6 +1656,7 @@ elem *toElem(Expression *e, IRState *irs)
e = el_combine(e, el_var(ts));
//elem_print(e);
}
e = el_combine(ezprefix, e);
}
else
{
Expand Down

0 comments on commit 11276b8

Please sign in to comment.