Skip to content

Commit 19d9ae5

Browse files
committed
Consider v.__ctor() an lvalue
1 parent 03bf6f0 commit 19d9ae5

2 files changed

Lines changed: 31 additions & 5 deletions

File tree

compiler/src/dmd/expressionsem.d

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -681,8 +681,19 @@ bool isLvalue(Expression _this)
681681
if (tf && tf.isRef)
682682
{
683683
if (auto dve = _this.e1.isDotVarExp())
684+
{
684685
if (dve.var.isCtorDeclaration())
685-
return false;
686+
{
687+
// Allow taking the address of explicit constructor calls,
688+
// but not (__stmp = S(), __stmp).__ctor().
689+
690+
auto ve = lastComma(dve.e1).isVarExp();
691+
if (ve && (ve.var.storage_class & STC.temp) != 0)
692+
return false;
693+
694+
return isLvalue(dve.e1);
695+
}
696+
}
686697
return true; // function returns a reference
687698
}
688699
return false;
@@ -775,8 +786,19 @@ bool canElideCopy(Expression e, Type to, bool checkMod = false)
775786
static bool visitCallExp(CallExp e)
776787
{
777788
if (auto dve = e.e1.isDotVarExp())
789+
{
778790
if (dve.var.isCtorDeclaration())
779-
return true;
791+
{
792+
// Allow (__stmp = S(), __stmp).__ctor() to be elided,
793+
// but force a copy for (s2 = s1.__ctor()).
794+
795+
auto ve = lastComma(dve.e1).isVarExp();
796+
if (ve && (ve.var.storage_class & STC.temp) != 0)
797+
return true;
798+
799+
return canElideCopy(dve.e1, e.type);
800+
}
801+
}
780802

781803
auto tb = e.e1.type.toBasetype();
782804
if (tb.ty == Tdelegate || tb.ty == Tpointer)

compiler/test/runnable/rvalue1.d

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -284,19 +284,23 @@ struct S12{
284284

285285
struct V12
286286
{
287-
S12 s;
288-
this(int) { s = S12(1); }
287+
S12 a, b;
288+
this(int) { a = b = S12(1); }
289289
}
290290

291291
S12 foo12()
292292
{
293-
return __rvalue(V12(1).s);
293+
return __rvalue(V12(1).a);
294294
}
295295

296296
void test12()
297297
{
298298
S12 s = foo12();
299299
assert(&s == s.ptr);
300+
301+
V12 v = V12(1);
302+
assert(&v.a == v.a.ptr);
303+
assert(&v.b == v.b.ptr);
300304
}
301305

302306
/********************************/

0 commit comments

Comments
 (0)