digitalmars.D.bugs - [Issue 1978] New: Wrong vtable call
- d-bugmail puremagic.com (154/154) Apr 08 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1978
- d-bugmail puremagic.com (79/79) Apr 08 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1978
- d-bugmail puremagic.com (4/4) Apr 08 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1978
- d-bugmail puremagic.com (28/28) Apr 08 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1978
- d-bugmail puremagic.com (9/9) May 11 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1978
http://d.puremagic.com/issues/show_bug.cgi?id=1978 Summary: Wrong vtable call Product: D Version: 1.028 Platform: PC OS/Version: All Status: NEW Severity: critical Priority: P2 Component: DMD AssignedTo: bugzilla digitalmars.com ReportedBy: benoit tionex.de In the following example, the program block if compiled with -g and dmd 1.026/1.028. See the comments, there are 3 possiblilities of changes, which should not change behaviour, but does make this program work. I tested this only on tango. Can someone confirm this bug also on phobos? and D2? extern(C) int printf(char*,...); public interface View(T){ // changing duplicate return type to View!(T) make it work public Dispenser!(T) duplicate (); public uint size (); public uint mutation (); public int opApply (int delegate (inout T value) dg); } public interface Dispenser(T) : View!(T){ public void removeAll (Iterator!(T) e); public void remove (Iterator!(T) e); public void removeAll (T element); public void remove (T element); } public interface Seq(T) : View!(T), // removing View!(T) interface make it work. Dispenser!(T) { public T get(int index); public alias get opIndex; } public interface Iterator(V) { public bool more(); public V get(); int opApply (int delegate (inout V value) dg); } public interface GuardIterator(V) : Iterator!(V){ public uint remaining(); } public abstract class AbstractIterator(T) : GuardIterator!(T) { private View!(T) view; private uint mutation; private uint togo; protected this (View!(T) v) { view = v; togo = v.size(); mutation = v.mutation(); } public final uint remaining() { return togo; } public final bool more() { return togo > 0 && mutation is view.mutation; } protected final void decRemaining() { --togo; } } class ArrayIterator(T) : AbstractIterator!(T) { private int row; private T[] array; public this (ArraySeq!(T) seq) { super (seq); array = seq.array; } public final T get() { decRemaining(); return array[row++]; } int opApply (int delegate (inout T value) dg) { int result; for (auto i=remaining(); i--;) { auto value = get(); if ((result = dg(value)) != 0) break; } return result; } } public abstract class Collection(T) : Dispenser!(T) { alias View!(T) ViewT; protected uint count; public final uint size() { return count; } public final uint mutation() { return 0; } abstract void removeAll(T element); abstract void remove (T element); abstract void removeAll (Iterator!(T) e); abstract void remove (Iterator!(T) e); } public abstract class SeqCollection(T) : Collection!(T), Seq!(T) { public abstract override void remove(T it); public abstract override void removeAll(T it); public void removeAll (Iterator!(T) e) { while (e.more) removeAll (e.get); } public void remove (Iterator!(T) e) { while (e.more) remove (e.get); } } public class ArraySeq(T) : SeqCollection!(T), Dispenser!(T) { public static int minCapacity = 16; package T array[]; public this () { this ( null, 0); } package this (T[] b, int c) { array = b; count = c; } public final Dispenser!(T) duplicate() { return null; } int opApply (int delegate (inout T value) dg){ auto scope iterator = new ArrayIterator!(T)(this); return iterator.opApply (dg); } public final T get(int index){ return array[index]; } public final override void remove(T element){} public final override void removeAll(T element){} public void remove(Iterator!(T) it){ super.remove(it); } public void removeAll(Iterator!(T) it){ super.removeAll(it); } } // removing this variable decl will make it work Seq!(Object) seq; void main(){ auto alist = new ArraySeq!(Object); foreach( el; alist ){ printf( "shall not come here.\n" ); } printf( "ready\n" ); } --
Apr 08 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1978 I reduced it more... Now the example prints: remove ready It does not block, but remove() is called without call. extern(C) int printf(char*,...); public interface View(T){ // changing duplicate return type to View!(T) make it work public Dispenser!(T) duplicate (); public uint mutation (); } public interface Dispenser(T) : View!(T){ public void removeAll (Iterator!(T) e); public void remove (Iterator!(T) e); public void removeAll (T element); public void remove (T element); } public interface Seq(T) : View!(T), // removing View!(T) interface make it work. Dispenser!(T) { } public interface Iterator(V) { int opApply (int delegate (inout V value) dg); } public abstract class AbstractIterator(T) : Iterator!(T) { protected this (View!(T) v) { v.mutation(); } } class ArrayIterator(T) : AbstractIterator!(T) { public this (ArraySeq!(T) seq) { super (seq); } int opApply (int delegate (inout T value) dg) { return 0; } } public abstract class Collection(T) : Dispenser!(T) { public final uint mutation() { return 0; } } // removing this intermediate class makes it work public abstract class SeqCollection(T) : Collection!(T), Seq!(T) { } public class ArraySeq(T) : SeqCollection!(T) , Dispenser!(T) // removing this makes it work, dispenser is already derived from SeqCollection { // public final Dispenser!(T) duplicate() { return null; } public final override void remove(T element){} public final override void removeAll(T element){} public void removeAll (Iterator!(T) e) { printf( "removeAll\n" ); } public void remove (Iterator!(T) e) { printf( "remove\n" ); } } //import tango.util.collection.model.Seq; //import tango.util.collection.ArraySeq; // removing this variable decl will make it work Seq!(Object) seq; void main(){ auto alist = new ArraySeq!(Object); auto scope iterator = new ArrayIterator!(Object)(alist); foreach( el; iterator ){ printf( "shall not come here.\n" ); } printf( "ready\n" ); } --
Apr 08 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1978 I verified the bug with dmd 1.028 and 2.012 with phobos. --
Apr 08 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1978 kamm-removethis incasoftware.de changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |wrong-code ------- Further simplification: extern(C) int printf(char*,...); interface InterfaceB(T) : InterfaceA {} interface InterfaceA{ // changing return type to InterfaceA makes it work InterfaceB!(Object) func (); } class Foo(T) : InterfaceB!(T) { InterfaceB!(Object) func() { return null; } } void main() { auto foo = new Foo!(Object); // without this call, segfault is gone foo.func(); printf("foo.func() call passed\n"); InterfaceA ifA = foo; assert(ifA !is null); ifA.func(); // segfault } --
Apr 08 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1978 bugzilla digitalmars.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |FIXED Fixed dmd 1.029 and 2.013 --
May 11 2008