[Issue 2224] New: Temporary assignment circumvents bug

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sun Jul 13 11:27:31 PDT 2008


http://d.puremagic.com/issues/show_bug.cgi?id=2224

           Summary: Temporary assignment circumvents bug
           Product: D
           Version: 2.012
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Keywords: wrong-code
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla at digitalmars.com
        ReportedBy: fasching at logic.at


Hi!

I encountered the following situation. If, in the 
code below, the assignment
   mem.data[d+i]=r(a+i);
is changed into
   uint rr=r(a+i); mem.data[d+i]=rr;
or
   int rr=r(a+i); mem.data[d+i]=rr;
the code works as it should.

Sorry for the strange code, I stripped my original
example down to the minimum size where this strange
behaviour is shown. (It also works with a mixin
instead of a stack class.) The .dups allow for
using dmd2, gdc-4.1 and gdc-4.2. No warnings are issued.
It does not depend on the optimisation switches
as far as I found out.

The example can be reproduced with:
dmd v2.012, gdc-4.1 (GCC) 4.1.3 20070831 and
gdc-4.2 (GCC) 4.2.3 20080225 (prerelease gdc 0.25 20071215, using dmd 1.022) 

Is this a bug or am I doing something wrong?
Any ideas?

Cheers
Oliver


import std.stdio;

class Stack(T)
{
        private uint len;
        private T[] dat;

        T[] data() { return dat[0..len]; }

        int length() { return len; }

        void push(T t) {
                if(dat.length<=len) dat.length=dat.length+32;
                dat[len]=t;
                len++;
        }

        void pushn(uint n) {
                len+=n;
                if(dat.length<len) dat.length=len+32;
        }
}

class termmem
{
        Stack!(uint) mem;
        this(){mem=new Stack!(uint);}

        uint cell(uint addr) { return mem.data[addr]; }
        uint head(uint addr) { return cell(deref(addr)); }

        uint deref(uint addr) {
                for(;;) {
                        uint c=mem.data[addr];
                        if(0!=(c & 0xf000_0000)) break;
                        if(c==addr) break;
                        addr=c;
                }
                return addr;
        }

        void dump() {
                char[] str(uint a) {
                        if(a==0x9000_0000) return "S".dup;
                        if(a==0xa000_0000) return "+".dup;
                        if(a==0xa000_0001) return "*".dup;
                        return " ".dup;
                }
                for(uint i=0; i<mem.length; i++) writefln("%+10x %+10x
%s",i,mem.data[i],str(mem.data[i]));
        }

        uint var() {
                uint d=mem.length;
                mem.push(d);
                return d;
        }

        uint f(uint fnId, uint[] arg...) { return f_(fnId,arg); }

        uint f_(uint fnId, uint[] arg) {
                uint a=fnId>>28;
                assert(a>0x8);
                a-=0x8;
                assert(a==arg.length);
                uint r=mem.length;
                mem.push(fnId);
                for(uint i=0; i<a; i++) {
                        uint w=arg[i];
                        uint t=w>>28;
                        assert(0==t || 0x8==t);
                        mem.push(w);
                }
                return r;
        }

        uint copyfskeleton(uint _addr)
        {
                uint r(uint a) {
                        a=deref(a);
                        uint c=head(a);
                        uint t=c>>28;
                        if(t==0 || t==0x8) return var();
                        assert(!(0<t && t<0x8));
                        t=t&7;
                        uint d=mem.length;
                        mem.push(c);
                        mem.pushn(t);
                        for(int i=1; i<=t; i++) {
                                mem.data[d+i]=r(a+i);
                                /+
                                // If code is changed to that it works as
expected.
                                uint rr=r(a+i);
                                mem.data[d+i]=rr;
                                +/
                        }
                        return d;
                }
                return r(_addr);
        }
}

int main(char[][])
{
        termmem T=new termmem;
        uint S(uint x) { return T.f(0x9000_0000,x); }
        uint P(uint x, uint y) { return T.f(0xa000_0000,x,y); }
        uint x=T.var;
        uint y=T.var;
        uint t=S(P(S(S(x)),x));
        T.dump();
        uint s=S(P(S(S(x)),S(x))); // if commented out, bad behaviour
disappears
        uint u=T.copyfskeleton(t);
        T.dump();
        return 0;
}


-- 



More information about the Digitalmars-d-bugs mailing list