Skip to content

Commit

Permalink
Merge pull request #6847 from WalterBright/fix17457
Browse files Browse the repository at this point in the history
fix Issue 17457 - Named Return Value Optimization (NRVO) not done wit…
merged-on-behalf-of: Andrei Alexandrescu <andralex@users.noreply.github.com>
  • Loading branch information
dlang-bot committed Jun 10, 2017
2 parents 51b5a07 + 2fd9691 commit 10e086a
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
27 changes: 26 additions & 1 deletion src/ddmd/s2ir.d
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ extern (C++) class S2irVisitor : Visitor

override void visit(ReturnStatement s)
{
//printf("s2ir.ReturnStatement: %s\n", s.toChars());
Blockx *blx = irs.blx;
BC bc;

Expand All @@ -790,6 +791,7 @@ extern (C++) class S2irVisitor : Visitor
if (retmethod == RETstack)
{
elem *es;
bool writetohp;

/* If returning struct literal, write result
* directly into return value
Expand All @@ -798,11 +800,34 @@ extern (C++) class S2irVisitor : Visitor
{
StructLiteralExp sle = cast(StructLiteralExp)s.exp;
sle.sym = irs.shidden;
writetohp = true;
}
/* Detect:
* structliteral.ctor(args)
* and construct directly into *shidden
*/
else if (s.exp.op == TOKcall)
{
auto ce = cast(CallExp)s.exp;
if (ce.e1.op == TOKdotvar)
{
auto dve = cast(DotVarExp)ce.e1;
auto fd = dve.var.isFuncDeclaration();
if (fd && fd.isCtorDeclaration())
{
if (dve.e1.op == TOKstructliteral)
{
auto sle = cast(StructLiteralExp)dve.e1;
sle.sym = irs.shidden;
writetohp = true;
}
}
}
}
e = toElemDtor(s.exp, irs);
assert(e);

if (s.exp.op == TOKstructliteral ||
if (writetohp ||
(func.nrvo_can && func.nrvo_var))
{
// Return value via hidden pointer passed as parameter
Expand Down
28 changes: 28 additions & 0 deletions test/runnable/sdtor.d
Original file line number Diff line number Diff line change
Expand Up @@ -2815,6 +2815,33 @@ void test9985()
static assert(is(typeof(retX) == F2));
}

/**********************************/

// https://issues.dlang.org/show_bug.cgi?id=17457

void delegate() dg17457;

struct S17457 {
ulong[10] data;

this(int seconds) {
dg17457 = &mfunc;
}
void mfunc() {}
}

auto foo17457() {
pragma(inline, false);
return S17457(18);
}

void test17457()
{
auto x = foo17457();
//printf("%p vs %p\n", &x, dg17457.ptr);
assert(&x == dg17457.ptr);
}

/**********************************/
// 9994

Expand Down Expand Up @@ -4546,6 +4573,7 @@ int main()
test9899();
test9907();
test9985();
test17457();
test9994();
test10094();
test10244();
Expand Down

0 comments on commit 10e086a

Please sign in to comment.