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;
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();
@ -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);
@ -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;

View file

@ -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*, ...);
/*******************************************/
@ -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()
@ -1314,6 +1357,7 @@ void main()
test63();
test64();
test65();
test18576();
printf("Success\n");
}