[Issue 1978] New: Wrong vtable call

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue Apr 8 01:40:54 PDT 2008


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 at digitalmars.com
        ReportedBy: benoit at 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" );
}


-- 



More information about the Digitalmars-d-bugs mailing list