Skip to content

Commit

Permalink
Merge pull request #7976 from WalterBright/fix5212
Browse files Browse the repository at this point in the history
fix Issue 5212 - no escape analysis for typesafe variadic function ar…
  • Loading branch information
WalterBright authored Mar 3, 2018
2 parents 65bc408 + be4ad4b commit de44987
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 7 deletions.
5 changes: 5 additions & 0 deletions src/dmd/dtemplate.d
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,12 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
fparam.storageClass &= (STC.in_ | STC.out_ | STC.ref_ | STC.lazy_ | STC.final_ | STC.TYPECTOR | STC.nodtor);
fparam.storageClass |= STC.parameter;
if (fvarargs == 2 && i + 1 == nfparams)
{
fparam.storageClass |= STC.variadic;
/* Don't need to set STC.scope_ because this will only
* be evaluated at compile time
*/
}
}
for (size_t i = 0; i < fparameters.dim; i++)
{
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ private bool functionParameters(Loc loc, Scope* sc, TypeFunction tf, Type tthis,
nargs++;
}

if (tf.varargs == 2 && i + 1 == nparams)
if (tf.varargs == 2 && i + 1 == nparams) // https://dlang.org/spec/function.html#variadic
{
//printf("\t\tvarargs == 2, p.type = '%s'\n", p.type.toChars());
{
Expand Down
10 changes: 10 additions & 0 deletions src/dmd/semantic3.d
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,17 @@ private extern(C++) final class Semantic3Visitor : Visitor
//printf("declaring parameter %s of type %s\n", v.toChars(), v.type.toChars());
stc |= STC.parameter;
if (f.varargs == 2 && i + 1 == nparams)
{
stc |= STC.variadic;
auto vtypeb = vtype.toBasetype();
if (vtypeb.ty == Tarray)
{
/* Since it'll be pointing into the stack for the array
* contents, it needs to be `scope`
*/
stc |= STC.scope_;
}
}
if (funcdecl.flags & FUNCFLAG.inferScope && !(fparam.storageClass & STC.scope_))
stc |= STC.maybescope;
stc |= fparam.storageClass & (STC.in_ | STC.out_ | STC.ref_ | STC.return_ | STC.scope_ | STC.lazy_ | STC.final_ | STC.TYPECTOR | STC.nodtor);
Expand Down
9 changes: 4 additions & 5 deletions test/fail_compilation/fail13902.d
Original file line number Diff line number Diff line change
Expand Up @@ -323,19 +323,18 @@ int[] testSlice2() { int[3] sa; int n; return sa[n..2][1..2]; }
/*
TEST_OUTPUT:
---
fail_compilation/fail13902.d(324): Error: returning `vda[0]` escapes a reference to parameter `vda`, perhaps annotate with `return`
fail_compilation/fail13902.d(325): Error: returning `vda[]` escapes a reference to variadic parameter `vda`
fail_compilation/fail13902.d(323): Error: returning `vda[0]` escapes a reference to parameter `vda`, perhaps annotate with `return`
---
*/
ref int testDynamicArrayVariadic1(int[] vda...) { return vda[0]; }
int[] testDynamicArrayVariadic2(int[] vda...) { return vda[]; }
@safe int[] testDynamicArrayVariadic2(int[] vda...) { return vda[]; }
int[3] testDynamicArrayVariadic3(int[] vda...) { return vda[0..3]; } // no error

/*
TEST_OUTPUT:
---
fail_compilation/fail13902.d(335): Error: returning `vsa[0]` escapes a reference to parameter `vsa`, perhaps annotate with `return`
fail_compilation/fail13902.d(336): Error: returning `vsa[]` escapes a reference to variadic parameter `vsa`
fail_compilation/fail13902.d(334): Error: returning `vsa[0]` escapes a reference to parameter `vsa`, perhaps annotate with `return`
fail_compilation/fail13902.d(335): Error: returning `vsa[]` escapes a reference to variadic parameter `vsa`
---
*/
ref int testStaticArrayVariadic1(int[3] vsa...) { return vsa[0]; }
Expand Down
17 changes: 17 additions & 0 deletions test/fail_compilation/fix5212.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* REQUIRED_ARGS: -dip1000
TEST_OUTPUT:
---
fail_compilation/fix5212.d(14): Error: scope variable `args_` assigned to `this` with longer lifetime
---
*/


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

class Foo {
int[] args;
@safe this(int[] args_...) {
args = args_;
}
}

2 changes: 1 addition & 1 deletion test/fail_compilation/retscope.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fail_compilation/retscope.d(23): Error: scope variable `p` may not be returned
fail_compilation/retscope.d(33): Error: returning `b ? nested1(& i) : nested2(& j)` escapes a reference to local variable `j`
fail_compilation/retscope.d(46): Error: scope variable `p` assigned to non-scope `q`
fail_compilation/retscope.d(48): Error: address of variable `i` assigned to `q` with longer lifetime
fail_compilation/retscope.d(49): Error: variadic variable `a` assigned to non-scope `b`
fail_compilation/retscope.d(49): Error: scope variable `a` assigned to non-scope `b`
fail_compilation/retscope.d(50): Error: reference to stack allocated value returned by `(*fp2)()` assigned to non-scope `q`
---
*/
Expand Down

0 comments on commit de44987

Please sign in to comment.