Thread overview | ||||||
---|---|---|---|---|---|---|
|
April 05, 2013 [dmd-internals] lambdaCheckForNestedRef not catching all closure vars. | ||||
---|---|---|---|---|
| ||||
Attachments:
| 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 Re: [dmd-internals] lambdaCheckForNestedRef not catching all closure vars. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | 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 Re: [dmd-internals] lambdaCheckForNestedRef not catching all closure vars. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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 Re: [dmd-internals] lambdaCheckForNestedRef not catching all closure vars. | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger Attachments:
| 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'; |
Copyright © 1999-2021 by the D Language Foundation