diff --git a/src/escape.d b/src/escape.d index 08897fd9c651..6d78a88bdf0c 100644 --- a/src/escape.d +++ b/src/escape.d @@ -192,10 +192,17 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag) VarDeclaration va; while (e1.op == TOKdotvar) e1 = (cast(DotVarExp)e1).e1; + if (e1.op == TOKvar) va = (cast(VarExp)e1).var.isVarDeclaration(); else if (e1.op == TOKthis) va = (cast(ThisExp)e1).var.isVarDeclaration(); + else if (e1.op == TOKindex) + { + auto ie = cast(IndexExp)e1; + if (ie.e1.op == TOKvar && ie.e1.type.toBasetype().ty == Tsarray) + va = (cast(VarExp)ie.e1).var.isVarDeclaration(); + } // Try to infer 'scope' for va if in a function not marked @system bool inferScope = false; @@ -1058,9 +1065,9 @@ private void escapeByRef(Expression e, EscapeByResults* er) DotVarExp dve = cast(DotVarExp)e.e1; if (dve.var.storage_class & STCreturn || tf.isreturn) { - if (dve.var.storage_class & STCscope) + if (dve.var.storage_class & STCscope || tf.isscope) escapeByValue(dve.e1, er); - else if (dve.var.storage_class & STCref) + else if (dve.var.storage_class & STCref || tf.isref) dve.e1.accept(this); } } diff --git a/test/fail_compilation/retscope.d b/test/fail_compilation/retscope.d index e65bc35b74a1..28ef214060e6 100644 --- a/test/fail_compilation/retscope.d +++ b/test/fail_compilation/retscope.d @@ -6,7 +6,7 @@ TEST_OUTPUT: fail_compilation/retscope.d(23): Error: scope variable p may not be returned fail_compilation/retscope.d(33): Error: escaping reference to local variable j fail_compilation/retscope.d(46): Error: scope variable p assigned to non-scope q -fail_compilation/retscope.d(48): Error: cannot take address of local i in @safe function test2 +fail_compilation/retscope.d(48): Error: address of variable i assigned to q with longer lifetime fail_compilation/retscope.d(49): Error: variadic 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 --- @@ -127,10 +127,10 @@ char[] bar9() @safe /*************************************************/ /* -TEST_OUTPUT: ---- -fail_compilation/retscope.d(143): To enforce @safe compiler allocates a closure unless the opApply() uses 'scope' ---- +// +// +//fail_compilation/retscope.d(143): To enforce @safe compiler allocates a closure unless the opApply() uses 'scope' +// */ struct S10 @@ -235,10 +235,10 @@ void* funretscope(scope dg_t ptr) @safe /* TEST_OUTPUT: --- -fail_compilation/retscope.d(247): Error: cannot implicitly convert expression (__lambda1) of type void* delegate() pure nothrow @nogc return @safe to void* delegate() @safe -fail_compilation/retscope.d(247): Error: cannot implicitly convert expression (__lambda1) of type void* delegate() pure nothrow @nogc return @safe to void* delegate() @safe -fail_compilation/retscope.d(248): Error: cannot implicitly convert expression (__lambda2) of type void* delegate() pure nothrow @nogc return @safe to void* delegate() @safe -fail_compilation/retscope.d(248): Error: cannot implicitly convert expression (__lambda2) of type void* delegate() pure nothrow @nogc return @safe to void* delegate() @safe +fail_compilation/retscope.d(249): Error: cannot implicitly convert expression (__lambda1) of type void* delegate() pure nothrow @nogc return @safe to void* delegate() @safe +fail_compilation/retscope.d(249): Error: cannot implicitly convert expression (__lambda1) of type void* delegate() pure nothrow @nogc return @safe to void* delegate() @safe +fail_compilation/retscope.d(250): Error: cannot implicitly convert expression (__lambda2) of type void* delegate() pure nothrow @nogc return @safe to void* delegate() @safe +fail_compilation/retscope.d(250): Error: cannot implicitly convert expression (__lambda2) of type void* delegate() pure nothrow @nogc return @safe to void* delegate() @safe --- */ @@ -349,3 +349,71 @@ int* bar11(scope int** x) @safe } int* foo11(int* x) @safe { return x; } + +/******************************************/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/********************************************/ + +void escape15() @safe +{ + int arg; + const(void)*[1] argsAddresses; + argsAddresses[0] = // MUST be an array assignment + (ref arg)@trusted{ return cast(const void*) &arg; }(arg); +} + + diff --git a/test/fail_compilation/test14238.d b/test/fail_compilation/test14238.d index 1ad582e70975..dd096f328953 100644 --- a/test/fail_compilation/test14238.d +++ b/test/fail_compilation/test14238.d @@ -10,7 +10,7 @@ fail_compilation/test14238.d(29): Error: escaping reference to stack allocated v @safe: -alias Fn = ref int delegate(); +alias Fn = ref int delegate() return; ref int foo(return scope Fn fn) { diff --git a/test/fail_compilation/test16193.d b/test/fail_compilation/test16193.d index ae84388d4841..e8b47d4f35b9 100644 --- a/test/fail_compilation/test16193.d +++ b/test/fail_compilation/test16193.d @@ -3,13 +3,13 @@ REQUIRED_ARGS: -transition=safe PERMUTE_ARGS: TEST_OUTPUT: --- -fail_compilation/test16193.d(22): To enforce @safe compiler allocates a closure unless the opApply() uses 'scope' -fail_compilation/test16193.d(34): To enforce @safe compiler allocates a closure unless the opApply() uses 'scope' -fail_compilation/test16193.d(41): To enforce @safe compiler allocates a closure unless the opApply() uses 'scope' fail_compilation/test16193.d(39): Error: function test16193.abc is @nogc yet allocates closures with the GC fail_compilation/test16193.d(41): test16193.abc.__foreachbody1 closes over variable x at fail_compilation/test16193.d(40) --- */ +//fail_compilation/test16193.d(22): To enforce @safe compiler allocates a closure unless the opApply() uses 'scope' +//fail_compilation/test16193.d(34): To enforce @safe compiler allocates a closure unless the opApply() uses 'scope' +//fail_compilation/test16193.d(41): To enforce @safe compiler allocates a closure unless the opApply() uses 'scope' // https://issues.dlang.org/show_bug.cgi?id=16193 diff --git a/test/fail_compilation/test16589.d b/test/fail_compilation/test16589.d index 9b94e3bebc49..10d0a9b058b5 100644 --- a/test/fail_compilation/test16589.d +++ b/test/fail_compilation/test16589.d @@ -2,12 +2,12 @@ REQUIRED_ARGS: -transition=safe TEST_OUTPUT: --- -fail_compilation/test16589.d(26): Error: cannot take address of parameter this in @safe function access1 -fail_compilation/test16589.d(31): Error: cannot take address of parameter this in @safe function access2 -fail_compilation/test16589.d(37): Error: cannot take address of parameter s in @safe function access3 -fail_compilation/test16589.d(42): Error: cannot take address of parameter s in @safe function access4 -fail_compilation/test16589.d(47): Error: cannot take address of parameter s in @safe function access5 -fail_compilation/test16589.d(52): Error: cannot take address of parameter s in @safe function access6 +fail_compilation/test16589.d(26): Error: escaping reference to local variable this +fail_compilation/test16589.d(31): Error: escaping reference to local variable this +fail_compilation/test16589.d(37): Error: escaping reference to local variable s +fail_compilation/test16589.d(42): Error: escaping reference to local variable s +fail_compilation/test16589.d(47): Error: escaping reference to local variable s +fail_compilation/test16589.d(52): Error: escaping reference to local variable s --- */