Merge pull request #7990 from WalterBright/fix18576

fix Issue 18576 - Compiler not doing RVO with auto returns
merged-on-behalf-of: Walter Bright <WalterBright@users.noreply.github.com>
This commit is contained in:
The Dlang Bot 2018-03-11 06:39:21 +01:00 committed by GitHub
commit 8b51a1d3d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 4 deletions

View file

@ -734,14 +734,26 @@ private extern (C++) class S2irVisitor : Visitor
sle.sym = irs.shidden; sle.sym = irs.shidden;
writetohp = true; writetohp = true;
} }
/* Detect: /* Detect function call that returns the same struct
* structliteral.ctor(args)
* and construct directly into *shidden * and construct directly into *shidden
*/ */
else if (s.exp.op == TOK.call) else if (s.exp.op == TOK.call)
{ {
auto ce = cast(CallExp)s.exp; 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 dve = cast(DotVarExp)ce.e1;
auto fd = dve.var.isFuncDeclaration(); auto fd = dve.var.isFuncDeclaration();
@ -754,6 +766,16 @@ private extern (C++) class S2irVisitor : Visitor
writetohp = true; 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); e = toElemDtor(s.exp, irs);
@ -787,6 +809,7 @@ private extern (C++) class S2irVisitor : Visitor
e = toElemDtor(s.exp, irs); e = toElemDtor(s.exp, irs);
assert(e); assert(e);
} }
L1:
elem_setLoc(e, s.loc); elem_setLoc(e, s.loc);
block_appendexp(blx.curblock, e); block_appendexp(blx.curblock, e);
bc = BCretexp; bc = BCretexp;

View file

@ -1,10 +1,10 @@
module test; module test;
import core.stdc.stdio;
import core.vararg; import core.vararg;
import std.stdio; import std.stdio;
import std.string; import std.string;
extern(C) int printf(const char*, ...);
/*******************************************/ /*******************************************/
@ -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() void main()
@ -1314,6 +1357,7 @@ void main()
test63(); test63();
test64(); test64();
test65(); test65();
test18576();
printf("Success\n"); printf("Success\n");
} }