diff --git a/src/escape.d b/src/escape.d index 2925a9c6d22b..08897fd9c651 100644 --- a/src/escape.d +++ b/src/escape.d @@ -901,6 +901,7 @@ private void escapeByValue(Expression e, EscapeByResults* er) */ private void escapeByRef(Expression e, EscapeByResults* er) { + //printf("[%s] escapeByRef, e: %s\n", e.loc.toChars(), e.toChars()); extern (C++) final class EscapeRefVisitor : Visitor { alias visit = super.visit; diff --git a/src/expression.d b/src/expression.d index aa8313c98785..5bcfa428358c 100644 --- a/src/expression.d +++ b/src/expression.d @@ -10749,6 +10749,28 @@ extern (C++) final class AddrExp : UnaExp } } } + else if (e1.op == TOKindex) + { + /* For: + * int[3] a; + * &a[i] + * check 'a' the same as for a regular variable + */ + IndexExp ei = cast(IndexExp)e1; + Type tyi = ei.e1.type.toBasetype(); + if (tyi.ty == Tsarray && ei.e1.op == TOKvar) + { + VarExp ve = cast(VarExp)ei.e1; + VarDeclaration v = ve.var.isVarDeclaration(); + if (v) + { + if (!checkAddressVar(v)) + return new ErrorExp(); + + ve.checkPurity(sc, v); + } + } + } else if (wasCond) { /* a ? b : c was transformed to *(a ? &b : &c), but we still diff --git a/test/fail_compilation/retscope.d b/test/fail_compilation/retscope.d index a94007dcb1fb..e65bc35b74a1 100644 --- a/test/fail_compilation/retscope.d +++ b/test/fail_compilation/retscope.d @@ -327,3 +327,25 @@ int* bar10( scope int** ptr ) @safe return *ptr; } +/******************************************/ + +/* +TEST_OUTPUT: +--- +fail_compilation/retscope.d(343): Error: cannot take address of scope local aa in @safe function escape11 +--- +*/ + +int* escape11() @safe +{ + int i; + int*[3] aa = [ &i, null, null ]; + return bar11(&aa[0]); +} + +int* bar11(scope int** x) @safe +{ + return foo11(*x); +} + +int* foo11(int* x) @safe { return x; }