Thread overview
[dmd-internals] lambdaCheckForNestedRef not catching all closure vars.
Apr 05, 2013
Iain Buclaw
Apr 05, 2013
Walter Bright
Apr 05, 2013
David Nadlinger
Apr 05, 2013
Iain Buclaw
April 05, 2013
Hi,

In the following example code:

---
import std.container;

void run (E) (lazy E expression)
{
  expression();
}

void main()
{
  Array!int a = [1, 2, 3];
  auto r = a.dup[];
  run(a.insertBefore(r, 42));
}
---

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.

In the above, the following is generated (in pseudo code)

---
void main()
{
   alias (main.chain)->a a;
   Range r;    //  Should be 'alias (main.chain)->r r';

   r = dup (&a);
   try {
      run ( {.object = main.chain, .func = __dgliteral} );
   }
   finally {
      fieldDtor (r);
   }
}

int __dgliteral (void* this)
{
   Range __cpcttmp;
   __cpctor (&__cpccttmp, &r);    // Should be '__cpctor (&__cpcttmp,
((main.chain) this)->r);
   return insertBefore (((main.chain) this)->a, __cpcttmp, 42);
}
---


Reason this appears to happen is because in the stage where it converts the following argument to a delegate:

a.insertBefore((Range __cpcttmp = __cpcttmp.__cpctor(r);\n , __cpcttmp), 42)

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.

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?


Thanks
-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';


April 05, 2013
On 4/5/2013 11:17 AM, Iain Buclaw wrote:
>
>
> 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?
>

Please file this as a bugzilla issue, and then do a pull request with the fix.
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

April 05, 2013
See http://forum.dlang.org/post/CAP9J_HXG8mTtnojU9YwYuSGZp1NQCdY0+7oeHyoQ2WhNR-dAuw@mail.gmail.com for a minimal example of a closure var not being detected.

What is you fix?

David


On 5 Apr 2013, at 21:01, Walter Bright wrote:
> On 4/5/2013 11:17 AM, Iain Buclaw wrote:
>>
>>
>> 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?
>>
>
> Please file this as a bugzilla issue, and then do a pull request with the fix.
> _______________________________________________
> dmd-internals mailing list
> dmd-internals@puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-internals
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

April 05, 2013
On 5 April 2013 20:12, David Nadlinger <code@klickverbot.at> wrote:

> See http://forum.dlang.org/post/**CAP9J_**HXG8mTtnojU9YwYuSGZp1NQCdY0+** 7oeHyoQ2WhNR-dAuw@mail.gmail.**com<http://forum.dlang.org/post/CAP9J_HXG8mTtnojU9YwYuSGZp1NQCdY0+7oeHyoQ2WhNR-dAuw@mail.gmail.com>for a minimal example of a closure var not being detected.
>
> What is you fix?
>
> David
>
>

With my fix, the closure var *is* detected pushed into closureVars in that bug you've posted, but needsClosure() still returns false on the function. In gdc this means that it puts 'a' on a stack frame. And the stackstomp() will override the value.


-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';