http://d.puremagic.com/issues/show_bug.cgi?id=8556
Summary: Using take results in a corrupted call to opSlice Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nob...@puremagic.com ReportedBy: jmdavisp...@gmx.com --- Comment #0 from Jonathan M Davis <jmdavisp...@gmx.com> 2012-08-17 02:41:15 PDT --- Okay. This program import std.algorithm; import std.range; import std.stdio; import std.string; import std.traits; struct Cycle(Range) if (isForwardRange!(Unqual!Range) && !isInfinite!(Unqual!Range)) { alias Unqual!Range R; R _original; size_t _index; this(R input, size_t index = 0) { _original = input; _index = index; } @property auto ref front() { return _original[_index % _original.length]; } enum bool empty = false; void popFront() { ++_index; } auto opSlice(size_t i, size_t j) { assert(j >= i, format("%s %s %s", i, j, _index)); writefln("%s %s %s", i, j, _index); return takeExactly(typeof(this)(_original.save, _index + i), j - i); } } Cycle!R cycle(R)(R input, size_t index = 0) if (isRandomAccessRange!(Unqual!R) && !isInfinite!(Unqual!R)) { return Cycle!R(input, index); } void main() { uint[] arr = [1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U]; auto t = take(cycle(arr), 20); auto cx = cycle(arr); auto slice = cx[23 .. 33]; assert(equal(slice, [4, 5, 6, 7, 8, 9, 10, 1, 2, 3]), format("%s", array(slice))); } seems to give different results depending on the architecture, and small tweaks to it seem to result in different results fairly easily. Given the code above, it should print out 23 33 0 and pass the assertions, but right now it prints out core.exception.AssertError@q.d(28): 140464871555008 10 0 and the exact number for the first index varies between runs of the program. If I were to change opSlice to take ints, then I get 0 10 0 core.exception.AssertError@q.d(48): [1,2,3,4,5,6,7,8,9,10] and the results actually seem to be consistent. If I remove the call to take, then the code works just fine. So, it looks like for some reason, that call to take is resulting in the indices to opSlice being corrupted, and rather than 22 and 33, it's more or less random, depending on what other code is there (code which should have _zero_ effect on the indices) and potentially changing between runs of the program. Interestingly enough, if I compile with -O, I get this error in opSlice: q.d(28): Error: variable j used before set q.d(28): Error: variable i used before set and if I compile with -inline, I get q.d(28): Error: function q.Cycle!(uint[]).Cycle.opSlice is a nested function and cannot be accessed from D main q.d(28): Error: function q.Cycle!(uint[]).Cycle.opSlice is a nested function and cannot be accessed from D main q.d(28): Error: function q.Cycle!(uint[]).Cycle.opSlice is a nested function and cannot be accessed from D main q.d(28): Error: function q.Cycle!(uint[]).Cycle.opSlice is a nested function and cannot be accessed from D main q.d(29): Error: function q.Cycle!(uint[]).Cycle.opSlice is a nested function and cannot be accessed from D main q.d(29): Error: function q.Cycle!(uint[]).Cycle.opSlice is a nested function and cannot be accessed from D main q.d(30): Error: function q.Cycle!(uint[]).Cycle.opSlice is a nested function and cannot be accessed from D main q.d(30): Error: function q.Cycle!(uint[]).Cycle.opSlice is a nested function and cannot be accessed from D main q.d(30): Error: function q.Cycle!(uint[]).Cycle.opSlice is a nested function and cannot be accessed from D main dmd: glue.c:735: virtual void FuncDeclaration::toObjFile(int): Assertion `!vthis->csym' failed. Aborted So, maybe there's something wrong with the lowering code? take does call the slice operator, but using the slice operator twice rather than calling take and then using it seems to work just fine. All in all, this looks really weird. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------