[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