Skip to content

Commit

Permalink
Merge pull request #7990 from WalterBright/fix18576
Browse files Browse the repository at this point in the history
fix Issue 18576 - Compiler not doing RVO with auto returns
merged-on-behalf-of: Walter Bright <WalterBright@users.noreply.github.com>
  • Loading branch information
dlang-bot committed Mar 11, 2018
2 parents 9380471 + 94f0bd6 commit 8b51a1d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
29 changes: 26 additions & 3 deletions src/dmd/s2ir.d
Expand Up @@ -734,14 +734,26 @@ private extern (C++) class S2irVisitor : Visitor
sle.sym = irs.shidden;
writetohp = true;
}
/* Detect:
* structliteral.ctor(args)
/* Detect function call that returns the same struct
* and construct directly into *shidden
*/
else if (s.exp.op == TOK.call)
{
auto ce = cast(CallExp)s.exp;
if (ce.e1.op == TOK.dotVariable)
if (ce.e1.op == TOK.variable || ce.e1.op == TOK.star)
{
Type t = ce.e1.type.toBasetype();
if (t.ty == Tdelegate)
t = t.nextOf();
if (t.ty == Tfunction && retStyle(cast(TypeFunction)t) == RET.stack)
{
irs.ehidden = el_var(irs.shidden);
e = toElemDtor(s.exp, irs);
e = el_una(OPaddr, TYnptr, e);
goto L1;
}
}
else if (ce.e1.op == TOK.dotVariable)
{
auto dve = cast(DotVarExp)ce.e1;
auto fd = dve.var.isFuncDeclaration();
Expand All @@ -754,6 +766,16 @@ private extern (C++) class S2irVisitor : Visitor
writetohp = true;
}
}
Type t = ce.e1.type.toBasetype();
if (t.ty == Tdelegate)
t = t.nextOf();
if (t.ty == Tfunction && retStyle(cast(TypeFunction)t) == RET.stack)
{
irs.ehidden = el_var(irs.shidden);
e = toElemDtor(s.exp, irs);
e = el_una(OPaddr, TYnptr, e);
goto L1;
}
}
}
e = toElemDtor(s.exp, irs);
Expand Down Expand Up @@ -787,6 +809,7 @@ private extern (C++) class S2irVisitor : Visitor
e = toElemDtor(s.exp, irs);
assert(e);
}
L1:
elem_setLoc(e, s.loc);
block_appendexp(blx.curblock, e);
bc = BCretexp;
Expand Down
46 changes: 45 additions & 1 deletion test/runnable/test28.d
@@ -1,10 +1,10 @@
module test;

import core.stdc.stdio;
import core.vararg;
import std.stdio;
import std.string;

extern(C) int printf(const char*, ...);

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

Expand Down Expand Up @@ -1247,6 +1247,49 @@ void test65()
}


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

void delegate() callback;

struct S66 {
int x;
@disable this(this);

this(int x) {
this.x = x;
callback = &inc;
}
void inc() {
x++;
}
}

auto f66()
{
return g66(); // RVO should be done
}

auto g66()
{
return h66(); // RVO should be done
}

auto h66()
{
return S66(100);
}

void test18576()
{
auto s = f66();
printf("%p vs %p\n", &s, callback.ptr);
callback();
printf("s.x = %d\n", s.x);
assert(s.x == 101);
assert(&s == callback.ptr);
}

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

void main()
Expand Down Expand Up @@ -1314,6 +1357,7 @@ void main()
test63();
test64();
test65();
test18576();

printf("Success\n");
}
Expand Down

0 comments on commit 8b51a1d

Please sign in to comment.