www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 13670] New: bug in assigning to dynamic array element

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 puremagic.com
          Reporter: ketmar 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.

--
Nov 01 2014