Skip to content

Commit

Permalink
Fix 23191 - scope parameter can be returned in @system code
Browse files Browse the repository at this point in the history
  • Loading branch information
dkorpel committed Jun 16, 2022
1 parent 3e2f56d commit d72e596
Show file tree
Hide file tree
Showing 11 changed files with 38 additions and 23 deletions.
4 changes: 2 additions & 2 deletions src/dmd/backend/cc.d
Expand Up @@ -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
Expand All @@ -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);


Expand Down
2 changes: 1 addition & 1 deletion src/dmd/backend/dtype.d
Expand Up @@ -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)
{
Expand Down
21 changes: 18 additions & 3 deletions src/dmd/escape.d
Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions 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
Expand Down
2 changes: 1 addition & 1 deletion test/fail_compilation/fail20108.d
Expand Up @@ -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
---
Expand Down
8 changes: 4 additions & 4 deletions test/fail_compilation/fail_scope.d
Expand Up @@ -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:
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion test/fail_compilation/previewin.d
Expand Up @@ -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`
Expand Down
6 changes: 3 additions & 3 deletions test/fail_compilation/retscope.d
Expand Up @@ -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
Expand Down Expand Up @@ -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
---
*/

Expand Down Expand Up @@ -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
---
*/

Expand Down
2 changes: 1 addition & 1 deletion 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`
---
*/
Expand Down
4 changes: 2 additions & 2 deletions test/fail_compilation/test17450.d
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion 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
---
*/

Expand Down

0 comments on commit d72e596

Please sign in to comment.