mirror of
https://github.com/dlang/dmd.git
synced 2025-04-28 06:00:13 +03:00
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:
commit
8b51a1d3d6
2 changed files with 71 additions and 4 deletions
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue