[Issue 13670] New: bug in assigning to dynamic array element
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Sat Nov 1 03:28:48 PDT 2014
https://issues.dlang.org/show_bug.cgi?id=13670
Issue ID: 13670
Summary: bug in assigning to dynamic array element
Product: D
Version: D2
Hardware: x86
OS: Linux
Status: NEW
Severity: critical
Priority: P1
Component: DMD
Assignee: nobody at puremagic.com
Reporter: ketmar at ketmar.no-ip.org
let's run this code:
struct Info {
size_t[] list;
}
size_t saveIt (ref Info info, size_t count) {
if (count < 1) return 666;
size_t idx = info.list.length;
info.list.length = idx+count;
foreach (; 0..count) {
info.list[idx] = saveIt(info, count-1); //!!!
assert(info.list[idx] != 0);
++idx;
}
return 666;
}
void main () {
auto info = Info();
saveIt(info, 2);
}
it should work, but it asserts. the fault line is marked by '!!!'.
if i'll change it to this:
auto n = saveIt(info, count-1);
info.list[idx] = n;
everything works ok.
i'm guessing that the bug is in evaluating left part of '=' operation before
the right part. assignment using the old array data address, but the array was
resized, so the old address is invalid. to prove that, let's change the code a
little:
size_t saveIt (ref Info info, size_t count) {
if (count < 1) return 666;
size_t idx = info.list.length;
info.list.length = idx+count;
foreach (; 0..count) {
auto p0 = &info.list[idx];
info.list[idx] = saveIt(info, count-1);
auto p1 = &info.list[idx];
if (info.list[idx] == 0) {
assert(*p0 != 0); //mk1
assert(*p1 != 0); //mk2
}
assert(info.list[idx] != 0);
++idx;
}
return 666;
}
line with 'mk1' should assert, but it doesn't! and line with 'mk2' asserts,
which proves that 'mk1' was really executed.
the bug is reproducible with gdc and dmd head on x86, without
optimisations turned on.
--
More information about the Digitalmars-d-bugs
mailing list