Skip to content

Commit 22f5ba7

Browse files
committed
fix Issue 20150 - -dip1000 return attribute must be explicit in pure functions
1 parent 2a42762 commit 22f5ba7

2 files changed

Lines changed: 36 additions & 6 deletions

File tree

src/dmd/escape.d

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,15 +1219,18 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
12191219

12201220
Dsymbol p = v.toParent2();
12211221

1222-
if ((v.isScope() || (v.storage_class & STC.maybescope)) &&
1223-
!(v.storage_class & STC.return_) &&
1222+
bool needsReturn = false;
1223+
if (!(v.storage_class & STC.return_) &&
12241224
v.isParameter() &&
1225-
!v.doNotInferReturn &&
1226-
sc.func.flags & FUNCFLAG.returnInprocess &&
12271225
p == sc.func)
12281226
{
1229-
inferReturn(sc.func, v); // infer addition of 'return'
1230-
continue;
1227+
if ((v.isScope() || (v.storage_class & STC.maybescope)) &&
1228+
sc.func.flags & FUNCFLAG.returnInprocess)
1229+
{
1230+
inferReturn(sc.func, v); // infer addition of 'return'
1231+
continue;
1232+
}
1233+
needsReturn = true; // needs 'return' annotation on parameter
12311234
}
12321235

12331236
if (v.isScope())
@@ -1275,6 +1278,17 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
12751278
result = false;
12761279
}
12771280
}
1281+
else if (needsReturn && sc.func.type.isTypeFunction().purity != PURE.impure && global.params.vsafe &&
1282+
sc._module && sc._module.isRoot())
1283+
{
1284+
/* Pure functions assume their parameters are `scope`, but they don't assume `return`.
1285+
* Hence, the annotation needs to be explicit.
1286+
*/
1287+
if (!gag)
1288+
error(e.loc, "`pure` function `%s` returns parameter `%s`, annotate with `return`",
1289+
sc.func.ident.toChars(), v.toChars());
1290+
result = true;
1291+
}
12781292
else
12791293
{
12801294
//printf("no infer for %s in %s, %d\n", v.toChars(), sc.func.ident.toChars(), __LINE__);

test/fail_compilation/retscope6.d

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,22 @@ T9 testfred()
170170
return fred(&i); // error
171171
}
172172

173+
174+
/* TEST_OUTPUT:
175+
---
176+
fail_compilation/retscope6.d(9505): Error: `pure` function `escape` returns parameter `r`, annotate with `return`
177+
---
178+
*/
179+
180+
#line 9500
181+
182+
// https://issues.dlang.org/show_bug.cgi?id=20150
183+
184+
int* escape(int* r) @safe pure
185+
{
186+
return r;
187+
}
188+
173189
/* TEST_OUTPUT:
174190
---
175191
fail_compilation/retscope6.d(10003): Error: scope variable `values` assigned to non-scope parameter `values` calling retscope6.escape

0 commit comments

Comments
 (0)