From d72e596128d4fc0ab928e3e86520e7d2fa54d14a Mon Sep 17 00:00:00 2001 From: Dennis Korpel Date: Thu, 16 Jun 2022 10:56:25 +0200 Subject: [PATCH] Fix 23191 - scope parameter can be returned in `@system` code --- src/dmd/backend/cc.d | 4 ++-- src/dmd/backend/dtype.d | 2 +- src/dmd/escape.d | 21 ++++++++++++++++++--- test/fail_compilation/fail17927.d | 8 ++++---- test/fail_compilation/fail20108.d | 2 +- test/fail_compilation/fail_scope.d | 8 ++++---- test/fail_compilation/previewin.d | 2 +- test/fail_compilation/retscope.d | 6 +++--- test/fail_compilation/test14238.d | 2 +- test/fail_compilation/test17450.d | 4 ++-- test/fail_compilation/test22818.d | 2 +- 11 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/dmd/backend/cc.d b/src/dmd/backend/cc.d index 432166f9bced..0157fc536672 100644 --- a/src/dmd/backend/cc.d +++ b/src/dmd/backend/cc.d @@ -1573,7 +1573,7 @@ nothrow: // template-parameter-list { return param_t_createTal(&this, p); } - param_t* search(char* id) // look for Pident matching id + param_t* search(char* id) return // look for Pident matching id { return param_t_search(&this, id); } int searchn(char* id); // look for Pident matching id, return index @@ -1592,7 +1592,7 @@ void param_t_print(const scope param_t* p); void param_t_print_list(scope param_t* p); uint param_t_length(scope param_t* p); param_t* param_t_createTal(scope param_t* p, param_t *ptali); -param_t* param_t_search(scope param_t* p, char *id); +param_t* param_t_search(return scope param_t* p, char *id); int param_t_searchn(param_t* p, char *id); diff --git a/src/dmd/backend/dtype.d b/src/dmd/backend/dtype.d index 9895f9cce612..fe6072cbb1b0 100644 --- a/src/dmd/backend/dtype.d +++ b/src/dmd/backend/dtype.d @@ -1647,7 +1647,7 @@ version (SCPP_HTOD) */ @trusted -param_t* param_t_search(scope param_t* p, char *id) +param_t* param_t_search(return scope param_t* p, char *id) { for (; p; p = p.Pnext) { diff --git a/src/dmd/escape.d b/src/dmd/escape.d index b111a6211d65..0646f57c5cde 100644 --- a/src/dmd/escape.d +++ b/src/dmd/escape.d @@ -1230,9 +1230,24 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag) !(!refs && sc.func.isFuncDeclaration().getLevel(pfunc, sc.intypeof) > 0) ) { - // https://issues.dlang.org/show_bug.cgi?id=17029 - result |= sc.setUnsafeDIP1000(gag, e.loc, "scope variable `%s` may not be returned", v); - continue; + if (v.isParameter() && !(v.storage_class & STC.return_)) + { + // https://issues.dlang.org/show_bug.cgi?id=23191 + if (!gag) + { + previewErrorFunc(sc.isDeprecated(), global.params.useDIP1000)(e.loc, + "scope parameter `%s` may not be returned", v.toChars() + ); + result = true; + continue; + } + } + else + { + // https://issues.dlang.org/show_bug.cgi?id=17029 + result |= sc.setUnsafeDIP1000(gag, e.loc, "scope variable `%s` may not be returned", v); + continue; + } } } else if (v.storage_class & STC.variadic && p == sc.func) diff --git a/test/fail_compilation/fail17927.d b/test/fail_compilation/fail17927.d index 410f30777066..cf610ff8d973 100644 --- a/test/fail_compilation/fail17927.d +++ b/test/fail_compilation/fail17927.d @@ -1,10 +1,10 @@ /* REQUIRED_ARGS: -preview=dip1000 * TEST_OUTPUT: --- -fail_compilation/fail17927.d(13): Error: scope variable `this` may not be returned -fail_compilation/fail17927.d(15): Error: scope variable `this` may not be returned -fail_compilation/fail17927.d(21): Error: scope variable `ptr` may not be returned -fail_compilation/fail17927.d(23): Error: scope variable `ptr` may not be returned +fail_compilation/fail17927.d(13): Error: scope parameter `this` may not be returned +fail_compilation/fail17927.d(15): Error: scope parameter `this` may not be returned +fail_compilation/fail17927.d(21): Error: scope parameter `ptr` may not be returned +fail_compilation/fail17927.d(23): Error: scope parameter `ptr` may not be returned --- */ // https://issues.dlang.org/show_bug.cgi?id=17927 diff --git a/test/fail_compilation/fail20108.d b/test/fail_compilation/fail20108.d index f768b89e6a4e..15845e1d2fcc 100644 --- a/test/fail_compilation/fail20108.d +++ b/test/fail_compilation/fail20108.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/fail20108.d(15): Error: address of variable `y` assigned to `x` with longer lifetime -fail_compilation/fail20108.d(16): Error: scope variable `x` may not be returned +fail_compilation/fail20108.d(16): Error: scope parameter `x` may not be returned fail_compilation/fail20108.d(23): Error: address of variable `y` assigned to `x` with longer lifetime fail_compilation/fail20108.d(24): Error: scope variable `x` may not be returned --- diff --git a/test/fail_compilation/fail_scope.d b/test/fail_compilation/fail_scope.d index 3e7637ff6679..3fac1678e69e 100644 --- a/test/fail_compilation/fail_scope.d +++ b/test/fail_compilation/fail_scope.d @@ -2,7 +2,10 @@ REQUIRED_ARGS: TEST_OUTPUT: --- -fail_compilation/fail_scope.d(40): Deprecation: scope variable `p` may not be returned +fail_compilation/fail_scope.d(30): Deprecation: scope parameter `da` may not be returned +fail_compilation/fail_scope.d(32): Deprecation: scope parameter `o` may not be returned +fail_compilation/fail_scope.d(33): Deprecation: scope parameter `dg` may not be returned +fail_compilation/fail_scope.d(40): Deprecation: scope parameter `p` may not be returned fail_compilation/fail_scope.d(45): Error: returning `cast(char[])string` escapes a reference to local variable `string` fail_compilation/fail_scope.d(63): Error: returning `s.bar()` escapes a reference to local variable `s` fail_compilation/fail_scope.d(74): Error: `fail_scope.foo8` called with argument types `(int)` matches both: @@ -16,9 +19,6 @@ fail_compilation/fail_scope.d(108): Deprecation: escaping reference to outer loc fail_compilation/fail_scope.d(127): Deprecation: returning `s.bar()` escapes a reference to local variable `s` fail_compilation/fail_scope.d(137): Error: returning `foo16226(i)` escapes a reference to local variable `i` --- -//fail_compilation/fail_scope.d(30): Error: scope variable `da` may not be returned -//fail_compilation/fail_scope.d(32): Error: scope variable `o` may not be returned -//fail_compilation/fail_scope.d(33): Error: scope variable `dg` may not be returned //fail_compilation/fail_scope.d(35): Error: scope variable `da` may not be returned //fail_compilation/fail_scope.d(37): Error: scope variable `o` may not be returned //fail_compilation/fail_scope.d(38): Error: scope variable `dg` may not be returned diff --git a/test/fail_compilation/previewin.d b/test/fail_compilation/previewin.d index b3beaf4c9d80..ce0cf926a132 100644 --- a/test/fail_compilation/previewin.d +++ b/test/fail_compilation/previewin.d @@ -10,7 +10,7 @@ fail_compilation/previewin.d(6): Error: function `previewin.takeFunction(void fu fail_compilation/previewin.d(6): cannot pass argument `__lambda3` of type `void function(ref const(real) x) pure nothrow @nogc @safe` to parameter `void function(in real) f` fail_compilation/previewin.d(15): Error: scope variable `arg` assigned to non-scope `myGlobal` fail_compilation/previewin.d(16): Error: scope variable `arg` assigned to non-scope `myGlobal` -fail_compilation/previewin.d(17): Error: scope variable `arg` may not be returned +fail_compilation/previewin.d(17): Error: scope parameter `arg` may not be returned fail_compilation/previewin.d(18): Error: scope variable `arg` assigned to `escape` with longer lifetime fail_compilation/previewin.d(22): Error: returning `arg` escapes a reference to parameter `arg` fail_compilation/previewin.d(22): perhaps annotate the parameter with `return` diff --git a/test/fail_compilation/retscope.d b/test/fail_compilation/retscope.d index 63ecbb77111c..93944040db9e 100644 --- a/test/fail_compilation/retscope.d +++ b/test/fail_compilation/retscope.d @@ -2,7 +2,7 @@ REQUIRED_ARGS: -preview=dip1000 TEST_OUTPUT: --- -fail_compilation/retscope.d(22): Error: scope variable `p` may not be returned +fail_compilation/retscope.d(22): Error: scope parameter `p` may not be returned fail_compilation/retscope.d(32): Error: returning `b ? nested1(& i) : nested2(& j)` escapes a reference to local variable `j` fail_compilation/retscope.d(45): Error: scope variable `p` assigned to non-scope `q` fail_compilation/retscope.d(47): Error: address of variable `i` assigned to `q` with longer lifetime @@ -149,7 +149,7 @@ S10* test10() /* TEST_OUTPUT: --- -fail_compilation/retscope.d(158): Error: scope variable `this` may not be returned +fail_compilation/retscope.d(158): Error: scope parameter `this` may not be returned --- */ @@ -218,7 +218,7 @@ void* escape3 (scope void* p) @safe { /* TEST_OUTPUT: --- -fail_compilation/retscope.d(229): Error: scope variable `ptr` may not be returned +fail_compilation/retscope.d(229): Error: scope parameter `ptr` may not be returned --- */ diff --git a/test/fail_compilation/test14238.d b/test/fail_compilation/test14238.d index e0d0b35c4d6e..a0e4d69b361f 100644 --- a/test/fail_compilation/test14238.d +++ b/test/fail_compilation/test14238.d @@ -1,7 +1,7 @@ /* REQUIRED_ARGS: -preview=dip1000 TEST_OUTPUT: --- -fail_compilation/test14238.d(20): Error: scope variable `fn` may not be returned +fail_compilation/test14238.d(20): Error: scope parameter `fn` may not be returned fail_compilation/test14238.d(28): Error: escaping reference to stack allocated value returned by `&baz` --- */ diff --git a/test/fail_compilation/test17450.d b/test/fail_compilation/test17450.d index 098adaae648f..ddf3f46fb129 100644 --- a/test/fail_compilation/test17450.d +++ b/test/fail_compilation/test17450.d @@ -33,8 +33,8 @@ struct S { /* TEST_OUTPUT: --- -fail_compilation/test17450.d(103): Error: scope variable `c` may not be returned -fail_compilation/test17450.d(106): Error: scope variable `this` may not be returned +fail_compilation/test17450.d(103): Error: scope parameter `c` may not be returned +fail_compilation/test17450.d(106): Error: scope parameter `this` may not be returned --- */ // https://issues.dlang.org/show_bug.cgi?id=17450 diff --git a/test/fail_compilation/test22818.d b/test/fail_compilation/test22818.d index ae96b3bc109d..5759415ead2f 100644 --- a/test/fail_compilation/test22818.d +++ b/test/fail_compilation/test22818.d @@ -1,7 +1,7 @@ /* REQUIRED_ARGS: -preview=dip1000 * TEST_OUTPUT: --- -fail_compilation/test22818.d(104): Error: scope variable `c` may not be returned +fail_compilation/test22818.d(104): Error: scope parameter `c` may not be returned --- */