<div dir="ltr"><div>Hi,<br><br></div>In the following example code:<br><br>---<br>import std.container;<br><br>void run (E) (lazy E expression)<br>{<br>  expression();<br>}<br><br>void main()<br>{<br>  Array!int a = [1, 2, 3];<br>


  auto r = a.dup[];<br>  run(a.insertBefore(r, 42));<br>}<br>---<br clear="all"><div><div><br></div><div>Although D main doesn't require a closure, closureVars are pushed into the function.  GDC depends on this being correct because chains are built in the frontend glue, as the backend can not handle the way delegates are supposed to work, and so never builds the function frame correctly.<br>


<br></div><div>In the above, the following is generated (in pseudo code)<br><br>---<br></div><div>void main()<br>{<br></div><div>   alias (main.chain)->a a;<br></div><div>   Range r;    //  Should be 'alias (main.chain)->r r';<br>
<br></div><div>   r = dup (&a);<br>
</div><div>   try {<br></div><div>      run ( {.object = main.chain, .func = __dgliteral} );<br>   }<br></div><div>   finally {<br></div><div>      fieldDtor (r);<br>   }<br></div><div>}<br><br></div><div>int __dgliteral (void* this)<br>

{<br></div><div>   Range __cpcttmp;<br></div><div>   __cpctor (&__cpccttmp, &r);    // Should be '__cpctor (&__cpcttmp, ((main.chain) this)->r);<br></div><div>   return insertBefore (((main.chain) this)->a, __cpcttmp, 42);<br>
</div><div>}<br></div><div>---<br></div><div><br><br></div><div>Reason this appears to happen is because in the stage where it converts the following argument to a delegate:<br><br>a.insertBefore((Range __cpcttmp = __cpcttmp.__cpctor(r);\n , __cpcttmp), 42)<br>
<br></div><div>It does not check if the RHS of the __cpcttmp assignment has any nested refs that could potentially need adding to the closure as well.<br><br></div><div>I've got a fix in the frontend for this, and it looks to not affect anything in the testsuite at least.  Is it worth pushing this in for a review?<br>
</div><div><br><br></div><div>Thanks<br></div><div>-- <br>Iain Buclaw<br><br>*(p < e ? p++ : p) = (c & 0x0f) + '0';
</div></div></div>