diff --git a/src/declaration.d b/src/declaration.d index f40562930bc2..e032d7f03351 100644 --- a/src/declaration.d +++ b/src/declaration.d @@ -2231,7 +2231,7 @@ extern (C++) class VarDeclaration : Declaration // delete this; Expression ec; ec = new VarExp(loc, this); - e = new DeleteExp(loc, ec); + e = new DeleteExp(loc, ec, true); e.type = Type.tvoid; break; } diff --git a/src/expression.d b/src/expression.d index ce0b02a6a570..9297defb91bd 100644 --- a/src/expression.d +++ b/src/expression.d @@ -11067,9 +11067,12 @@ extern (C++) final class NotExp : UnaExp */ extern (C++) final class DeleteExp : UnaExp { - extern (D) this(Loc loc, Expression e) + bool isRAII; // true if called automatically as a result of scoped destruction + + extern (D) this(Loc loc, Expression e, bool isRAII) { super(loc, TOKdelete, __traits(classInstanceSize, DeleteExp), e); + this.isRAII = isRAII; } override Expression semantic(Scope* sc) @@ -11184,8 +11187,9 @@ extern (C++) final class DeleteExp : UnaExp return new ErrorExp(); } - // unsafe - if (!sc.intypeof && sc.func && sc.func.setUnsafe()) + if (!sc.intypeof && sc.func && + !isRAII && + sc.func.setUnsafe()) { error("%s is not @safe but is used in @safe function %s", toChars(), sc.func.toChars()); err = true; diff --git a/src/expression.h b/src/expression.h index bf5869561c56..bcf95eb4b196 100644 --- a/src/expression.h +++ b/src/expression.h @@ -906,6 +906,7 @@ class NotExp : public UnaExp class DeleteExp : public UnaExp { + bool isRAII; public: Expression *semantic(Scope *sc); Expression *toBoolean(Scope *sc); diff --git a/src/parse.d b/src/parse.d index 1f359a8df7c9..fb3099374fbc 100644 --- a/src/parse.d +++ b/src/parse.d @@ -7616,7 +7616,7 @@ final class Parser : Lexer case TOKdelete: nextToken(); e = parseUnaryExp(); - e = new DeleteExp(loc, e); + e = new DeleteExp(loc, e, false); break; case TOKcast: // cast(type) expression diff --git a/test/compilable/test16747.d b/test/compilable/test16747.d new file mode 100644 index 000000000000..a0badc2bba73 --- /dev/null +++ b/test/compilable/test16747.d @@ -0,0 +1,13 @@ +/* +PERMUTE_ARGS: +*/ + +class C { @safe ~this() { } } +class D : C { } + +void fwd() @safe +{ + scope o = new Object(); + scope c = new C(); + scope d = new D(); +} diff --git a/test/runnable/testscope.d b/test/runnable/testscope.d index 18bf11a4bb03..07c6a7de31d4 100644 --- a/test/runnable/testscope.d +++ b/test/runnable/testscope.d @@ -260,6 +260,15 @@ void test7049() @safe /********************************************/ +// https://issues.dlang.org/show_bug.cgi?id=16747 + +void test16747() @safe +{ + scope o = new Object(); +} + +/********************************************/ + void main() { test1(); @@ -274,6 +283,7 @@ void main() test10(); test7435(); test7049(); + test16747(); printf("Success\n"); }