Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions src/dmd/escape.d
Original file line number Diff line number Diff line change
Expand Up @@ -1219,15 +1219,18 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)

Dsymbol p = v.toParent2();

if ((v.isScope() || (v.storage_class & STC.maybescope)) &&
!(v.storage_class & STC.return_) &&
bool needsReturn = false;
if (!(v.storage_class & STC.return_) &&
v.isParameter() &&
!v.doNotInferReturn &&
sc.func.flags & FUNCFLAG.returnInprocess &&
p == sc.func)
{
inferReturn(sc.func, v); // infer addition of 'return'
continue;
if ((v.isScope() || (v.storage_class & STC.maybescope)) &&
sc.func.flags & FUNCFLAG.returnInprocess)
{
inferReturn(sc.func, v); // infer addition of 'return'
continue;
}
needsReturn = true; // needs 'return' annotation on parameter
}

if (v.isScope())
Expand Down Expand Up @@ -1275,6 +1278,17 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
result = false;
}
}
else if (needsReturn && sc.func.type.isTypeFunction().purity != PURE.impure && global.params.vsafe &&
sc._module && sc._module.isRoot())
{
/* Pure functions assume their parameters are `scope`, but they don't assume `return`.
* Hence, the annotation needs to be explicit.
*/
if (!gag)
error(e.loc, "`pure` function `%s` returns parameter `%s`, annotate with `return`",
sc.func.ident.toChars(), v.toChars());
result = true;
}
else
{
//printf("no infer for %s in %s, %d\n", v.toChars(), sc.func.ident.toChars(), __LINE__);
Expand Down
2 changes: 1 addition & 1 deletion test/fail_compilation/fail20108.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
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(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
---
*/


@safe auto test(scope int* x)
{
int y = 69;
Expand Down
16 changes: 16 additions & 0 deletions test/fail_compilation/retscope6.d
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,22 @@ T9 testfred()
return fred(&i); // error
}


/* TEST_OUTPUT:
---
fail_compilation/retscope6.d(9505): Error: `pure` function `escape20150` returns parameter `r`, annotate with `return`
---
*/

#line 9500

// https://issues.dlang.org/show_bug.cgi?id=20150

int* escape20150(int* r) @safe pure
{
return r;
}

/* TEST_OUTPUT:
---
fail_compilation/retscope6.d(10003): Error: scope variable `values` assigned to non-scope parameter `values` calling retscope6.escape
Expand Down