Skip to content

Commit

Permalink
Issue 7516 - Postblit not called for structs returned from a ternary …
Browse files Browse the repository at this point in the history
…operator
  • Loading branch information
ibuclaw committed Jul 23, 2017
1 parent 366c8e9 commit 3f497ef
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 11 deletions.
28 changes: 21 additions & 7 deletions src/expression.c
Expand Up @@ -1130,7 +1130,7 @@ bool arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt)
continue;
}

e = e->isLvalue() ? callCpCtor(sc, e) : valueNoDtor(e);
e = doCopyOrMove(sc, e);

if (t0 && !t0->equals(e->type))
{
Expand Down Expand Up @@ -1349,6 +1349,24 @@ Expression *callCpCtor(Scope *sc, Expression *e)
return e;
}

/************************************************
* Handle the postblit call on lvalue, or the move of rvalue.
*/
Expression *doCopyOrMove(Scope *sc, Expression *e)
{
if (e->op == TOKquestion)
{
CondExp *ce = (CondExp *)e;
ce->e1 = doCopyOrMove(sc, ce->e1);
ce->e2 = doCopyOrMove(sc, ce->e2);
}
else
{
e = e->isLvalue() ? callCpCtor(sc, e) : valueNoDtor(e);
}
return e;
}

/****************************************
* Now that we know the exact type of the function we're calling,
* the arguments[] need to be adjusted:
Expand Down Expand Up @@ -1651,10 +1669,6 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
else
arg = toDelegate(arg, arg->type, sc);
}
else
{
// arg = arg->isLvalue() ? callCpCtor(sc, arg) : valueNoDtor(arg);
}

//printf("arg: %s\n", arg->toChars());
//printf("type: %s\n", arg->type->toChars());
Expand Down Expand Up @@ -1874,7 +1888,7 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
}
else if (ts)
{
arg = arg->isLvalue() ? callCpCtor(sc, arg) : valueNoDtor(arg);
arg = doCopyOrMove(sc, arg);
}
else if (anythrow && firstthrow <= i && i <= lastthrow && gate)
{
Expand Down Expand Up @@ -12038,7 +12052,7 @@ Expression *CatAssignExp::semantic(Scope *sc)
if (e2->checkPostblit(sc, tb2))
return new ErrorExp();
e2 = e2->castTo(sc, tb1next);
e2 = e2->isLvalue() ? callCpCtor(sc, e2) : valueNoDtor(e2);
e2 = doCopyOrMove(sc, e2);
}
else if (tb1->ty == Tarray &&
(tb1next->ty == Tchar || tb1next->ty == Twchar) &&
Expand Down
2 changes: 1 addition & 1 deletion src/expression.h
Expand Up @@ -72,7 +72,7 @@ TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s);
Expression *valueNoDtor(Expression *e);
int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1);
Expression *resolveAliasThis(Scope *sc, Expression *e, bool gag = false);
Expression *callCpCtor(Scope *sc, Expression *e);
Expression *doCopyOrMove(Scope *sc, Expression *e);
Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, Expression **pe0);
Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, IntervalExp *ie, Expression **pe0);
Expression *integralPromotions(Expression *e, Scope *sc);
Expand Down
4 changes: 2 additions & 2 deletions src/func.c
Expand Up @@ -1791,8 +1791,8 @@ void FuncDeclaration::semantic3(Scope *sc)
/* Bugzilla 10789:
* If NRVO is not possible, all returned lvalues should call their postblits.
*/
if (!nrvo_can && exp->isLvalue())
exp = callCpCtor(sc2, exp);
if (!nrvo_can)
exp = doCopyOrMove(sc2, exp);

checkEscape(sc2, exp, false);
}
Expand Down
2 changes: 1 addition & 1 deletion src/struct.c
Expand Up @@ -1303,7 +1303,7 @@ bool StructDeclaration::fit(Loc loc, Scope *sc, Expressions *elements, Type *sty
if (e->op == TOKerror)
return false;

(*elements)[i] = e->isLvalue() ? callCpCtor(sc, e) : valueNoDtor(e);
(*elements)[i] = doCopyOrMove(sc, e);
}
return true;
}
Expand Down

0 comments on commit 3f497ef

Please sign in to comment.