Bug 13244 – Wrong code with -inline and foreach/map/all
Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86
OS
All
Creation time
2014-08-03T07:03:00Z
Last change time
2015-11-06T06:09:09Z
Keywords
pull, wrong-code
Assigned to
nobody
Creator
dlang-bugzilla
Comments
Comment #0 by dlang-bugzilla — 2014-08-03T07:03:34Z
//////////////// test.d ///////////////
import std.algorithm;
import std.range;
void main()
{
auto arr = [[cast(ubyte)1]];
foreach (ref x; arr)
1.iota.map!(c => x[c]).array();
}
///////////////////////////////////////
Running this program results in an access violation when built with -inline.
Comment #1 by dlang-bugzilla — 2014-08-03T07:35:43Z
Comment #2 by verylonglogin.reg — 2014-09-02T08:02:26Z
Probably a duplicate of Issue 13083.
Comment #3 by olaa81 — 2014-10-13T15:08:36Z
Similar issue with map/array:
-- main.d --
import std.algorithm;
import failsinline;
void main()
{
auto fail = new FailsInline();
}
-- main.d --
-- failsinline.d --
import std.algorithm;
import std.array;
void failsinline()
{
auto transform = (int i) => i;
[0].map!transform.array;
}
-- failsinline.d --
'rdmd main.d' works fine.
'rdmd -inline main.d' gives object.Error@(0): Access Violation.
Removing the std.algorithm import from main.d makes it work fine.
Same issue in dmd 2.066, 2.066-rc2 and 2.067-b1.
Comment #4 by k.hara.pg — 2015-07-02T10:32:11Z
Reduced case in comment #1 does not reproduce segfault with 2.068 git-head.
Another reduction is:
struct MapResult(alias fun)
{
int[] input;
@property front() { return fun(input[0]); }
}
int[] array(R)(R r)
{
int[] a;
a ~= r.front;
return a;
}
void main()
{
auto arr = [[cast(ubyte)1]];
foreach (ref x; arr)
{
auto m = MapResult!(c => x[c])([0]);
array(m);
}
}
Comment #5 by k.hara.pg — 2015-07-03T05:49:36Z
(In reply to Kenji Hara from comment #4)
> Reduced case in comment #1 does not reproduce segfault with 2.068 git-head.
OK, I confirmed that the original issue might be a dup of issue 14366, but that fix (#PR 4505) had contained problem.
void ToElemVisitor::visit(DotVarExp *) in e2ir.c
elem *e = toElem(dve->e1, irs);
Type *tb1 = dve->e1->type->toBasetype();
if (tb1->ty != Tclass && tb1->ty != Tpointer)
e = addressElem(e, tb1);
e = el_bin(OPadd, TYnptr, e, el_long(TYsize_t, v->offset));
if (v->isRef() || v->isOut()) // 14366 fix
e = el_una(OPind, TYptr, e); // Line 3367
e = el_una(OPind, totym(dve->type), e);
if (tybasic(e->Ety) == TYstruct)
{
e->ET = Type_toCtype(dve->type);
}
el_setLoc(e,dve->loc);
result = e;
At the line 3367, the indirection result is typed as TYptr - it's wrong. In 32bit/64 code gen, we should use TYnptr.
By the difference, the indirection result will be stored in 16bit size register, and then the corrupted pointer will cause Access Violation.
I'm getting this again with dmd 2.069.
With the files below, running rdmd -g -inline main.d I get:
object.Error@(0): Access Violation
----------------
0x00821014
0x0040221A in D3std5array135__T5arrayTS3std9algorithm9iteration87__T9MapResultS67_D11failsinline11FailsInline7146BC2938FC1915EBA515935C5C811A
0x0040247F in void failsinline.FailsInline.failsinline() at E:\source\dice\failsinline.d(9)
0x00402027 in _Dmain at E:\source\dice\main.d(7)
0x00402BF7 in D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv
0x00402BBB in void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll()
0x00402ABC in _d_run_main
0x004023F0 in main at E:\source\dice\main.d(7)
0x0041D0F5 in mainCRTStartup
0x77693744 in BaseThreadInitThunk
0x77BBA064 in RtlSetCurrentTransaction
0x77BBA02F in RtlSetCurrentTransaction
When removing the std.algorithm import from main.d or compiling without -inline it works fine.
-- main.d --
import std.algorithm;
import failsinline;
void main()
{
auto fail = new FailsInline();
fail.failsinline();
}
-- main.d --
-- failsinline.d --
import std.algorithm : map;
import std.array : array;
class FailsInline
{
void failsinline()
{
auto transform = (int i) => i;
[0].map!transform.array;
}
}
-- failsinline.d --
Comment #10 by dlang-bugzilla — 2015-11-04T22:37:34Z
(In reply to Ola Østtveit from comment #9)
> I'm getting this again with dmd 2.069.
How do you know it's the same bug?
None of the examples that I posted still reproduced. The bug, as reported here, has been fixed and is still fixed.
In fact, your bug looks pretty different because it depends on the presence an import that shouldn't do anything in practice (std.algorithm in main.d).
You should probably file this as a separate issue.
Comment #11 by k.hara.pg — 2015-11-06T06:09:09Z
(In reply to Vladimir Panteleev from comment #10)
> (In reply to Ola Østtveit from comment #9)
> > I'm getting this again with dmd 2.069.
>
> You should probably file this as a separate issue.
I separated the another wrong-code bug into issue 15295.