Skip to content

Commit

Permalink
fix Issue 20183 - Assigning statement scope of struct literal or temp…
Browse files Browse the repository at this point in the history
…orary to variable with longer lifetime
  • Loading branch information
WalterBright committed Jun 10, 2020
1 parent 74190e5 commit 37a695f
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
23 changes: 23 additions & 0 deletions src/dmd/escape.d
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import dmd.errors;
import dmd.expression;
import dmd.func;
import dmd.globals;
import dmd.id;
import dmd.identifier;
import dmd.init;
import dmd.mtype;
Expand Down Expand Up @@ -889,6 +890,28 @@ ByRef:
continue;
}

if (va && ee.op == TOK.call && ee.type.toBasetype().ty == Tstruct &&
!(va.storage_class & STC.temp) && va.ident != Id.withSym &&
sc.func.setUnsafe())
{
if (!gag)
error(ee.loc, "address of struct temporary returned by `%s` assigned to longer lived variable `%s`",
ee.toChars(), va.toChars());
result = true;
continue;
}

if (va && ee.op == TOK.structLiteral &&
!(va.storage_class & STC.temp) && va.ident != Id.withSym &&
sc.func.setUnsafe())
{
if (!gag)
error(ee.loc, "address of struct literal `%s` assigned to longer lived variable `%s`",
ee.toChars(), va.toChars());
result = true;
continue;
}

if (va && !va.isDataseg() && !va.doNotInferScope)
{
if (!va.isScope() && inferScope)
Expand Down
28 changes: 28 additions & 0 deletions test/fail_compilation/fail20183.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* REQUIRED_ARGS: -preview=dip1000
TEST_OUTPUT:
---
fail_compilation/fail20183.d(1016): Error: cannot modify constant expression `S(0).i`
fail_compilation/fail20183.d(1017): Error: address of struct temporary returned by `s()` assigned to longer lived variable `q`
---
*/

#line 1000

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

@safe:

int* addr(return ref int b) { return &b; }

struct S
{
int i;
}

S s() { return S(); }

void test()
{
int* p = addr(S().i); // struct literal
int* q = addr(s().i); // struct temporary
}
2 changes: 1 addition & 1 deletion test/fail_compilation/retscope.d
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ fail_compilation/retscope.d(33): Error: returning `b ? nested1(& i) : nested2(&
fail_compilation/retscope.d(46): Error: scope variable `p` assigned to non-scope `q`
fail_compilation/retscope.d(48): Error: address of variable `i` assigned to `q` with longer lifetime
fail_compilation/retscope.d(49): Error: scope variable `a` assigned to non-scope `b`
fail_compilation/retscope.d(50): Error: reference to stack allocated value returned by `(*fp2)()` assigned to non-scope `q`
fail_compilation/retscope.d(50): Error: address of struct temporary returned by `(*fp2)()` assigned to longer lived variable `q`
---
*/

Expand Down

0 comments on commit 37a695f

Please sign in to comment.