Bug 12839 – std.parallelism with nested functions and lambdas. Segfault
Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
All
Creation time
2014-06-02T10:02:03Z
Last change time
2018-06-13T08:51:08Z
Assigned to
No Owner
Creator
John Colvin
Comments
Comment #0 by john.loughran.colvin — 2014-06-02T10:02:03Z
import std.parallelism;
import std.algorithm;
auto loo(int a, int[] b)
{
auto inner(int c)
{
return a;
}
return b.map!((x) => () => inner(x));
}
void main()
{
defaultPoolThreads = 1;
auto res = loo(3, [1,2,3]);
auto jobs = taskPool.map!"a()"(res);
}
This segfaults. More details to come.
Comment #1 by john.loughran.colvin — 2014-06-02T11:03:22Z
Interestingly, the following works fine. It should be the same as the lambda-based version, no?
import std.parallelism;
import std.algorithm;
auto loo(int a, int[] b)
{
auto inner(int c)
{
return a;
}
auto wrapper(int x)
{
auto wrapperInner()
{
return inner(x);
}
return &wrapperInner;
}
return b.map!wrapper;
}
void main()
{
defaultPoolThreads = 1;
auto res = loo(3, [1,2,3]);
auto jobs = taskPool.map!"a()"(res);
assert(jobs.front() == 3);
}
Comment #2 by john.loughran.colvin — 2014-06-02T11:04:35Z
sorry, ignore the () on jobs.front
Comment #3 by mxfomin — 2014-08-14T06:58:09Z
Fails on win64 too.
Comment #4 by sinkuupump — 2015-01-19T04:38:07Z
Even replacing "taskPool.amap" with "map!"a()".array", it still segfaults.
import std.algorithm;
import std.array;
auto loo(int a, int[] b)
{
auto inner(int c)
{
return a; // debugger caught SEGV at this line
}
return b.map!((x) => () => inner(x));
}
void main()
{
auto res = loo(3, [1,2,3]);
auto jobs = map!"a()"(res).array; // evaluate eagerly
}
I reduced 'map' version, and found that just returning "() => () => inner()" and calling it segfaults. IIUC this seems a compiler bug.
auto loo(int a)
{
auto inner()
{
return a; // debugger caught SEGV at this line
}
return () => () => inner();
}
void main()
{
assert(loo(3)()() == 3);
}
Comment #5 by mxfomin — 2015-05-12T12:26:17Z
Now it gives ice.
auto loo(int a)
{
auto inner()
{
return a; // debugger caught SEGV at this line
}
return () => () => inner();
}
void main()
{
assert(loo(3)()() == 3);
}
DMD v2.068-devel-df9b8af-dirty DEBUG
dmd: toir.c:183: elem* getEthis(Loc, IRState*, Dsymbol*): Assertion `thisfd->isNested() || thisfd->vthis' failed.
Aborted
Comment #6 by post-dlang-issues — 2016-05-21T12:56:28Z
See also issue #16051, which deals with the same ICE. Not sure if it's a duplicate, though.
Comment #7 by razvan.nitu1305 — 2018-06-13T08:51:08Z
All the examples in this bug report now compile successfully. However, Issue 16051 is still valid. Closing as fixed.