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
Reduced: //////////////// test.d /////////////// struct MapResult(alias fun) { @property empty() { return false; } void popFront() { } @property front() { return fun(0); } } auto map(alias fun)() { return MapResult!fun(); } void all(Range)(Range haystack) { foreach (e; haystack) if (e) return; } void main() { auto arr = [[1]]; foreach (ref x; arr) map!(c => x[c]).all; } ///////////////////////////////////////
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.
Comment #6 by k.hara.pg — 2015-07-03T12:50:26Z
Comment #7 by k.hara.pg — 2015-07-03T12:53:44Z
*** Issue 13083 has been marked as a duplicate of this issue. ***
Comment #8 by github-bugzilla — 2015-08-30T14:55:48Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/7dd243d69d4d2525eebc7e73f94f9df215fbeb3a fix Issue 13244 - Wrong code with -inline and foreach/map/all https://github.com/D-Programming-Language/dmd/commit/a7717a0ee3708346d44f3b9ff237d18a4fedb549 Merge pull request #4796 from 9rnsr/fix13244 Issue 13244 - Wrong code with -inline and foreach/map/all
Comment #9 by olaa81 — 2015-11-04T22:26:41Z
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.