Thread overview
An occurence of a bug which was fixed in DMD a while ago
Nov 20, 2014
Koz Ross
Nov 20, 2014
Iain Buclaw
Nov 20, 2014
Koz Ross
November 20, 2014
The bug is similar to https://issues.dlang.org/show_bug.cgi?id=6998. Specifically, here is the code that can be used to demonstrate it. I'm using GDC 4.9.1 (according to gdc --version).

module badbh;

import std.container, std.string, std.stdio;

class Node {
  size_t val;
  Node next;

  this (size_t val) {
    this.val = val;
  }

  override string toString() {
    if (next is null) {
      return format("%s", val);
    } else {
      return format("%s, %s", val, next.toString());
    }
  }
}

void main () {
  //sets up the demo structure
  auto n = new Node(40);
  n.next = new Node(30);
  n.next.next = new Node(10);
  n.next.next.next = new Node(20);
  writeln(n); //should yield "40, 30, 10, 20"
  auto t2 = top2(n);
  writeln(n); //watch the segfaults
}

Node[] top2 (Node n) {
  auto heap = BinaryHeap!(Array!Node, function bool (Node a, Node b){return a.val > b.val;})();
  Node[] nodes;
  auto ptr = n;
  while (ptr !is null) {
    heap.insert(ptr);
    ptr = ptr.next;
  }
  for (auto i = 0; i < 2; i++) {
    nodes ~= heap.front;
    heap.removeFront;
  }
  assert(nodes.length == 2);
  //some sanity checks to show my code isn't logically FUBAR
  assert(nodes[0] !is null);
  assert(nodes[1] !is null);
  assert(nodes[0].val == 10);
  assert(nodes[1].val == 20);
  return nodes;
}

The comments are self-explanatory. This destructive behaviour occurs *only* when the heap is in a different scope to the structure - if you were to copy all the code in top2 into main, the segfault wouldn't happen.

I know that this is definitely a GDC thing - the same code under DMD works correctly (i.e. prints the whole linked structure and doesn't segfault).
November 20, 2014
On 20 Nov 2014 01:45, "Koz Ross via D.gnu" <d.gnu@puremagic.com> wrote:
>
> The bug is similar to https://issues.dlang.org/show_bug.cgi?id=6998.
Specifically, here is the code that can be used to demonstrate it. I'm using GDC 4.9.1 (according to gdc --version).
>
> module badbh;
>
> import std.container, std.string, std.stdio;
>
> class Node {
>   size_t val;
>   Node next;
>
>   this (size_t val) {
>     this.val = val;
>   }
>
>   override string toString() {
>     if (next is null) {
>       return format("%s", val);
>     } else {
>       return format("%s, %s", val, next.toString());
>     }
>   }
> }
>
> void main () {
>   //sets up the demo structure
>   auto n = new Node(40);
>   n.next = new Node(30);
>   n.next.next = new Node(10);
>   n.next.next.next = new Node(20);
>   writeln(n); //should yield "40, 30, 10, 20"
>   auto t2 = top2(n);
>   writeln(n); //watch the segfaults
> }
>
> Node[] top2 (Node n) {
>   auto heap = BinaryHeap!(Array!Node, function bool (Node a, Node
b){return a.val > b.val;})();
>   Node[] nodes;
>   auto ptr = n;
>   while (ptr !is null) {
>     heap.insert(ptr);
>     ptr = ptr.next;
>   }
>   for (auto i = 0; i < 2; i++) {
>     nodes ~= heap.front;
>     heap.removeFront;
>   }
>   assert(nodes.length == 2);
>   //some sanity checks to show my code isn't logically FUBAR
>   assert(nodes[0] !is null);
>   assert(nodes[1] !is null);
>   assert(nodes[0].val == 10);
>   assert(nodes[1].val == 20);
>   return nodes;
> }
>
> The comments are self-explanatory. This destructive behaviour occurs
*only* when the heap is in a different scope to the structure - if you were to copy all the code in top2 into main, the segfault wouldn't happen.
>
> I know that this is definitely a GDC thing - the same code under DMD
works correctly (i.e. prints the whole linked structure and doesn't
segfault).

Looking at the date it was fixed in DMD, the next release merge should resolve that.

Iain.


November 20, 2014
On Thursday, 20 November 2014 at 07:31:52 UTC, Iain Buclaw via D.gnu wrote:
> Looking at the date it was fixed in DMD, the next release merge should
> resolve that.
>
> Iain.

When will that be?