Skip to content

Commit

Permalink
fix Issue 15193 - DIP25 (implementation): Lifetimes of temporaries tr…
Browse files Browse the repository at this point in the history
…acked incorrectly
  • Loading branch information
WalterBright committed Jul 1, 2016
1 parent feb06a7 commit f2c50d0
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 8 deletions.
22 changes: 14 additions & 8 deletions src/escape.d
Expand Up @@ -8,6 +8,8 @@

module ddmd.escape;

import core.stdc.stdio : printf;

import ddmd.declaration;
import ddmd.dscope;
import ddmd.dsymbol;
Expand Down Expand Up @@ -242,14 +244,16 @@ bool checkEscape(Scope* sc, Expression e, bool gag)
* e = expression to check
* gag = do not print error messages
* Returns:
* true if referencess to the stack can escape
* true if references to the stack can escape
*/
bool checkEscapeRef(Scope* sc, Expression e, bool gag)
{
//import core.stdc.stdio : printf;
//printf("[%s] checkEscapeRef, e = %s\n", e.loc.toChars(), e.toChars());
//printf("current function %s\n", sc.func.toChars());
//printf("parent2 function %s\n", sc.func.toParent2().toChars());
version (none)
{
printf("[%s] checkEscapeRef, e = %s\n", e.loc.toChars(), e.toChars());
printf("current function %s\n", sc.func.toChars());
printf("parent2 function %s\n", sc.func.toParent2().toChars());
}

extern (C++) final class EscapeRefVisitor : Visitor
{
Expand Down Expand Up @@ -298,10 +302,11 @@ bool checkEscapeRef(Scope* sc, Expression e, bool gag)
v.storage_class |= STCreturn;
if (v == sc.func.vthis)
{
sc.func.storage_class |= STCreturn;
TypeFunction tf = cast(TypeFunction)sc.func.type;
if (tf.ty == Tfunction)
{
//printf("'this' too\n");
//printf("'this' too %p %s\n", tf, sc.func.toChars());
tf.isreturn = true;
}
}
Expand Down Expand Up @@ -451,10 +456,11 @@ bool checkEscapeRef(Scope* sc, Expression e, bool gag)
}
}
// If 'this' is returned by ref, check it too
if (tf.isreturn && e.e1.op == TOKdotvar && t1.ty == Tfunction)
if (e.e1.op == TOKdotvar && t1.ty == Tfunction)
{
DotVarExp dve = cast(DotVarExp)e.e1;
dve.e1.accept(this);
if (dve.var.storage_class & STCreturn || tf.isreturn)
dve.e1.accept(this);
}
}
else
Expand Down
19 changes: 19 additions & 0 deletions test/fail_compilation/test15193.d
@@ -0,0 +1,19 @@
/* REQUIRED_ARGS: -dip25
TEST_OUTPUT:
---
fail_compilation/test15193.d(17): Error: escaping reference to local variable s
---
*/


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

ref int foo()@safe{
struct S{
int x;
ref int bar() { return x; }
}
S s;
return s.bar();
}

0 comments on commit f2c50d0

Please sign in to comment.