diff -uNr dmd-1.024/dmd/src/dmd/cast.c dmd-1.025/dmd/src/dmd/cast.c --- dmd-1.024/dmd/src/dmd/cast.c 2007-09-03 08:30:44.000000000 +0200 +++ dmd-1.025/dmd/src/dmd/cast.c 2007-12-21 18:31:40.000000000 +0100 @@ -547,30 +547,27 @@ */ Expression *Expression::castTo(Scope *sc, Type *t) -{ Expression *e; - Type *tb; - +{ //printf("Expression::castTo(this=%s, t=%s)\n", toChars(), t->toChars()); #if 0 printf("Expression::castTo(this=%s, type=%s, t=%s)\n", toChars(), type->toChars(), t->toChars()); #endif - e = this; - tb = t->toBasetype(); - type = type->toBasetype(); - if (tb != type) + if (type == t) + return this; + Expression *e = this; + Type *tb = t->toBasetype(); + Type *typeb = type->toBasetype(); + if (tb != typeb) { - if (tb->ty == Tbit && isBit()) - ; - // Do (type *) cast of (type [dim]) - else if (tb->ty == Tpointer && - type->ty == Tsarray + if (tb->ty == Tpointer && + typeb->ty == Tsarray ) { //printf("Converting [dim] to *\n"); - if (type->size(loc) == 0) + if (typeb->size(loc) == 0) e = new NullExp(loc); else e = new AddrExp(loc, e); @@ -579,8 +576,8 @@ else if (tb->ty == Tdelegate && type->ty != Tdelegate) { TypeDelegate *td = (TypeDelegate *)tb; - TypeFunction *tf = (TypeFunction *)td->next; - return toDelegate(sc, tf->next); + TypeFunction *tf = (TypeFunction *)td->nextOf(); + return toDelegate(sc, tf->nextOf()); } #endif else @@ -588,6 +585,11 @@ e = new CastExp(loc, e, tb); } } + else + { + e = e->copy(); // because of COW for assignment to e->type + } + assert(e != this); e->type = t; //printf("Returning: %s\n", e->toChars()); return e; @@ -595,47 +597,62 @@ Expression *RealExp::castTo(Scope *sc, Type *t) -{ - if (type->isreal() && t->isreal()) - type = t; - else if (type->isimaginary() && t->isimaginary()) - type = t; - else - return Expression::castTo(sc, t); - return this; +{ Expression *e = this; + if (type != t) + { + if ((type->isreal() && t->isreal()) || + (type->isimaginary() && t->isimaginary()) + ) + { e = copy(); + e->type = t; + } + else + e = Expression::castTo(sc, t); + } + return e; } Expression *ComplexExp::castTo(Scope *sc, Type *t) -{ - if (type->iscomplex() && t->iscomplex()) - type = t; - else - return Expression::castTo(sc, t); - return this; +{ Expression *e = this; + if (type != t) + { + if (type->iscomplex() && t->iscomplex()) + { e = copy(); + e->type = t; + } + else + e = Expression::castTo(sc, t); + } + return e; } Expression *NullExp::castTo(Scope *sc, Type *t) -{ Expression *e; +{ NullExp *e; Type *tb; //printf("NullExp::castTo(t = %p)\n", t); - committed = 1; - e = this; + if (type == t) + { + committed = 1; + return this; + } + e = (NullExp *)copy(); + e->committed = 1; tb = t->toBasetype(); - type = type->toBasetype(); - if (tb != type) + e->type = type->toBasetype(); + if (tb != e->type) { // NULL implicitly converts to any pointer type or dynamic array - if (type->ty == Tpointer && type->next->ty == Tvoid && + if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tvoid && (tb->ty == Tpointer || tb->ty == Tarray || tb->ty == Taarray || tb->ty == Tdelegate)) { #if 0 if (tb->ty == Tdelegate) { TypeDelegate *td = (TypeDelegate *)tb; - TypeFunction *tf = (TypeFunction *)td->next; + TypeFunction *tf = (TypeFunction *)td->nextOf(); if (!tf->varargs && !(tf->arguments && tf->arguments->dim) @@ -648,8 +665,7 @@ } else { - return Expression::castTo(sc, t); - //e = new CastExp(loc, e, tb); + return e->Expression::castTo(sc, t); } } e->type = t; @@ -919,23 +935,31 @@ Expression *TupleExp::castTo(Scope *sc, Type *t) -{ - for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)exps->data[i]; - e = e->castTo(sc, t); - exps->data[i] = (void *)e; +{ TupleExp *e = (TupleExp *)copy(); + e->exps = (Expressions *)exps->copy(); + for (size_t i = 0; i < e->exps->dim; i++) + { Expression *ex = (Expression *)e->exps->data[i]; + ex = ex->castTo(sc, t); + e->exps->data[i] = (void *)ex; } - return this; + return e; } Expression *ArrayLiteralExp::castTo(Scope *sc, Type *t) { +#if 0 + printf("ArrayLiteralExp::castTo(this=%s, type=%s, t=%s)\n", + toChars(), type->toChars(), t->toChars()); +#endif + if (type == t) + return this; + ArrayLiteralExp *e = this; Type *typeb = type->toBasetype(); Type *tb = t->toBasetype(); if ((tb->ty == Tarray || tb->ty == Tsarray) && (typeb->ty == Tarray || typeb->ty == Tsarray) && - tb->next->toBasetype()->ty != Tvoid) + tb->nextOf()->toBasetype()->ty != Tvoid) { if (tb->ty == Tsarray) { TypeSArray *tsa = (TypeSArray *)tb; @@ -943,46 +967,56 @@ goto L1; } + e = (ArrayLiteralExp *)copy(); + e->elements = (Expressions *)elements->copy(); for (int i = 0; i < elements->dim; i++) - { Expression *e = (Expression *)elements->data[i]; - e = e->castTo(sc, tb->next); - elements->data[i] = (void *)e; + { Expression *ex = (Expression *)elements->data[i]; + ex = ex->castTo(sc, tb->nextOf()); + e->elements->data[i] = (void *)ex; } - type = t; - return this; + e->type = t; + return e; } if (tb->ty == Tpointer && typeb->ty == Tsarray) { - type = typeb->next->pointerTo(); + e = (ArrayLiteralExp *)copy(); + e->type = typeb->nextOf()->pointerTo(); } L1: - return Expression::castTo(sc, t); + return e->Expression::castTo(sc, t); } Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t) { + if (type == t) + return this; + AssocArrayLiteralExp *e = this; Type *typeb = type->toBasetype(); Type *tb = t->toBasetype(); if (tb->ty == Taarray && typeb->ty == Taarray && - tb->next->toBasetype()->ty != Tvoid) + tb->nextOf()->toBasetype()->ty != Tvoid) { + e = (AssocArrayLiteralExp *)copy(); + e->keys = (Expressions *)keys->copy(); + e->values = (Expressions *)values->copy(); assert(keys->dim == values->dim); for (size_t i = 0; i < keys->dim; i++) - { Expression *e = (Expression *)values->data[i]; - e = e->castTo(sc, tb->next); - values->data[i] = (void *)e; - - e = (Expression *)keys->data[i]; - e = e->castTo(sc, ((TypeAArray *)tb)->key); - keys->data[i] = (void *)e; + { Expression *ex = (Expression *)values->data[i]; + ex = ex->castTo(sc, tb->nextOf()); + e->values->data[i] = (void *)ex; + + ex = (Expression *)keys->data[i]; + ex = ex->castTo(sc, ((TypeAArray *)tb)->index); + e->keys->data[i] = (void *)ex; } - type = t; - return this; + e->type = t; + return e; } L1: - return Expression::castTo(sc, t); + return e->Expression::castTo(sc, t); } + Expression *SymOffExp::castTo(Scope *sc, Type *t) { Type *tb; diff -uNr dmd-1.024/dmd/src/dmd/expression.c dmd-1.025/dmd/src/dmd/expression.c --- dmd-1.024/dmd/src/dmd/expression.c 2007-11-25 00:07:44.000000000 +0100 +++ dmd-1.025/dmd/src/dmd/expression.c 2007-12-21 02:44:52.000000000 +0100 @@ -1758,7 +1758,7 @@ em = s->isEnumMember(); if (em) { - e = em->value; + e = em->value->copy(); e = e->semantic(sc); return e; } diff -uNr dmd-1.024/dmd/src/dmd/init.c dmd-1.025/dmd/src/dmd/init.c --- dmd-1.024/dmd/src/dmd/init.c 2007-08-31 17:40:00.000000000 +0200 +++ dmd-1.025/dmd/src/dmd/init.c 2007-12-29 22:42:30.000000000 +0100 @@ -179,7 +179,7 @@ s = ad->search(loc, id, 0); if (!s) { - error("'%s' is not a member of '%s'", id->toChars(), t->toChars()); + error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars()); continue; } diff -uNr dmd-1.024/dmd/src/dmd/interpret.c dmd-1.025/dmd/src/dmd/interpret.c --- dmd-1.024/dmd/src/dmd/interpret.c 2007-09-04 20:53:12.000000000 +0200 +++ dmd-1.025/dmd/src/dmd/interpret.c 2007-12-31 01:18:14.000000000 +0100 @@ -57,7 +57,7 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *arguments) { #if LOG - printf("FuncDeclaration::interpret() %s\n", toChars()); + printf("\n********\nFuncDeclaration::interpret(istate = %p) %s\n", istate, toChars()); printf("cantInterpret = %d, semanticRun = %d\n", cantInterpret, semanticRun); #endif if (global.errors) @@ -161,7 +161,15 @@ else { /* Value parameters */ - earg = earg->interpret(&istatex); + Type *ta = arg->type->toBasetype(); + if (ta->ty == Tsarray && earg->op == TOKaddress) + { + /* Static arrays are passed by a simple pointer. + * Skip past this to get at the actual arg. + */ + earg = ((AddrExp *)earg)->e1; + } + earg = earg->interpret(istate ? istate : &istatex); if (earg == EXP_CANT_INTERPRET) return NULL; v->value = earg; @@ -177,13 +185,13 @@ Expressions valueSaves; if (istate) { - //printf("saving state...\n"); + //printf("saving local variables...\n"); valueSaves.setDim(istate->vars.dim); for (size_t i = 0; i < istate->vars.dim; i++) { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i]; if (v) { - //printf("\tsaving [%d] %s = %s\n", i, v->toChars(), v->value->toChars()); + //printf("\tsaving [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : ""); valueSaves.data[i] = v->value; v->value = NULL; } @@ -230,10 +238,13 @@ { /* Restore the variable values */ + //printf("restoring local variables...\n"); for (size_t i = 0; i < istate->vars.dim; i++) { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i]; if (v) - v->value = (Expression *)valueSaves.data[i]; + { v->value = (Expression *)valueSaves.data[i]; + //printf("\trestoring [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : ""); + } } } @@ -904,6 +915,8 @@ { #if LOG printf("Expression::interpret() %s\n", toChars()); + printf("type = %s\n", type->toChars()); + dump(0); #endif return EXP_CANT_INTERPRET; } @@ -949,7 +962,11 @@ SymbolDeclaration *s = d->isSymbolDeclaration(); if (v) { +#if V2 + if ((v->isConst() || v->isInvariant()) && v->init && !v->value) +#else if (v->isConst() && v->init) +#endif { e = v->init->toExpression(); if (e && !e->type) e->type = v->type; @@ -1001,7 +1018,11 @@ else if (v->init->isVoidInitializer()) e = NULL; } +#if V2 + else if (s == v && (v->isConst() || v->isInvariant()) && v->init) +#else else if (s == v && v->isConst() && v->init) +#endif { e = v->init->toExpression(); if (!e) e = EXP_CANT_INTERPRET; @@ -1416,8 +1437,16 @@ */ if (v->value && v->value->op == TOKvar) { - ve = (VarExp *)v->value; - v = ve->var->isVarDeclaration(); + VarExp *ve2 = (VarExp *)v->value; + if (ve2->var->isSymbolDeclaration()) + { + /* This can happen if v is a struct initialized to + * 0 using an __initZ SymbolDeclaration from + * TypeStruct::defaultInit() + */ + } + else + v = ve2->var->isVarDeclaration(); assert(v); } @@ -1445,6 +1474,7 @@ { if (i == istate->vars.dim) { istate->vars.push(v); + //printf("\tadding %s to istate\n", v->toChars()); break; } if (v == (VarDeclaration *)istate->vars.data[i]) @@ -1797,7 +1827,27 @@ { FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration(); if (fd) - { // Inline .dup + { +#if V2 + enum BUILTIN b = fd->isBuiltin(); + if (b) + { Expressions args; + args.setDim(arguments->dim); + for (size_t i = 0; i < args.dim; i++) + { + Expression *earg = (Expression *)arguments->data[i]; + earg = earg->interpret(istate); + if (earg == EXP_CANT_INTERPRET) + return earg; + args.data[i] = (void *)earg; + } + e = eval_builtin(b, &args); + if (!e) + e = EXP_CANT_INTERPRET; + } + else +#endif + // Inline .dup if (fd->ident == Id::adDup && arguments && arguments->dim == 2) { e = (Expression *)arguments->data[1]; @@ -1812,7 +1862,7 @@ Expression *eresult = fd->interpret(istate, arguments); if (eresult) e = eresult; - else if (fd->type->toBasetype()->nextOf()->ty == Tvoid) + else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors) e = EXP_VOID_INTERPRET; else error("cannot evaluate %s at compile time", toChars()); diff -uNr dmd-1.024/dmd/src/dmd/mars.c dmd-1.025/dmd/src/dmd/mars.c --- dmd-1.024/dmd/src/dmd/mars.c 2007-11-01 19:41:44.000000000 +0100 +++ dmd-1.025/dmd/src/dmd/mars.c 2007-12-03 14:21:34.000000000 +0100 @@ -60,7 +60,7 @@ copyright = "Copyright (c) 1999-2007 by Digital Mars"; written = "written by Walter Bright"; - version = "v1.024"; + version = "v1.025"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); diff -uNr dmd-1.024/dmd/src/phobos/etc/c/zlib/linux.mak dmd-1.025/dmd/src/phobos/etc/c/zlib/linux.mak --- dmd-1.024/dmd/src/phobos/etc/c/zlib/linux.mak 2007-11-27 21:19:24.000000000 +0100 +++ dmd-1.025/dmd/src/phobos/etc/c/zlib/linux.mak 2008-01-01 00:49:16.000000000 +0100 @@ -74,4 +74,5 @@ echo hello world | minigzip | minigzip -d clean: - $(RM) $(OBJS) zlib.a example minigzip minigzip.o test foo.gz + $(RM) $(OBJS) zlib.a example.o example minigzip minigzip.o test foo.gz + diff -uNr dmd-1.024/dmd/src/phobos/linux.mak dmd-1.025/dmd/src/phobos/linux.mak --- dmd-1.024/dmd/src/phobos/linux.mak 2007-11-27 21:19:24.000000000 +0100 +++ dmd-1.025/dmd/src/phobos/linux.mak 2008-01-01 00:49:12.000000000 +0100 @@ -198,17 +198,17 @@ #$(LIB) : $(OBJS) internal/gc/dmgc.a linux.mak -$(LIB) : $(OBJS) internal/gc/dmgc.a $(ZLIB_OBJS) linux.mak +$(LIB) : $(OBJS) $(GC_OBJS) $(ZLIB_OBJS) linux.mak rm -f $(LIB) ar -r $@ $(OBJS) $(ZLIB_OBJS) $(GC_OBJS) ########################################################### -internal/gc/dmgc.a: +$(GC_OBJS): # cd internal/gc # make -f linux.mak dmgc.a # cd ../.. - make -C ./internal/gc -f linux.mak dmgc.a + make -C ./internal/gc -f linux.mak $(ZLIB_OBJS): # cd etc/c/zlib @@ -594,3 +594,6 @@ clean: $(RM) $(LIB) $(OBJS) unittest unittest.o + make -C ./internal/gc -f linux.mak clean + make -C ./etc/c/zlib -f linux.mak clean + diff -uNr dmd-1.024/dmd/src/phobos/std/c/string.d dmd-1.025/dmd/src/phobos/std/c/string.d --- dmd-1.024/dmd/src/phobos/std/c/string.d 2007-11-27 21:19:24.000000000 +0100 +++ dmd-1.025/dmd/src/phobos/std/c/string.d 2008-01-01 00:49:14.000000000 +0100 @@ -38,3 +38,9 @@ { int memicmp(char* s1, char* s2, size_t n); /// } + +version (linux) +{ + char* strerror_r(int errnum, char* buf, size_t buflen); /// +} + diff -uNr dmd-1.024/dmd/src/phobos/std/file.d dmd-1.025/dmd/src/phobos/std/file.d --- dmd-1.024/dmd/src/phobos/std/file.d 2007-11-27 21:19:24.000000000 +0100 +++ dmd-1.025/dmd/src/phobos/std/file.d 2008-01-01 00:49:12.000000000 +0100 @@ -845,8 +845,7 @@ private import std.date; private import std.c.linux.linux; - -extern (C) char* strerror(int); +private import std.c.string; /*********************************** */ @@ -867,7 +866,8 @@ } this(char[] name, uint errno) - { char* s = strerror(errno); + { char[80] buf = void; + auto s = strerror_r(errno, buf.ptr, buf.length); this(name, std.string.toString(s).dup); this.errno = errno; } diff -uNr dmd-1.024/dmd/src/phobos/std/loader.d dmd-1.025/dmd/src/phobos/std/loader.d --- dmd-1.024/dmd/src/phobos/std/loader.d 2007-11-27 21:19:24.000000000 +0100 +++ dmd-1.025/dmd/src/phobos/std/loader.d 2008-01-01 00:49:12.000000000 +0100 @@ -468,7 +468,15 @@ this(uint errcode) { + version (linux) + { + char[80] buf = void; + super(std.string.toString(strerror_r(errcode, buf.ptr, buf.length)).dup); + } + else + { super(std.string.toString(strerror(errcode)).dup); + } } } diff -uNr dmd-1.024/dmd/src/phobos/std/math.d dmd-1.025/dmd/src/phobos/std/math.d --- dmd-1.024/dmd/src/phobos/std/math.d 2007-11-27 21:19:24.000000000 +0100 +++ dmd-1.025/dmd/src/phobos/std/math.d 2008-01-01 00:49:12.000000000 +0100 @@ -70,7 +70,7 @@ { this(string msg) { - super(msg ~ "not implemented"); + super(msg ~ " not implemented"); } } @@ -856,6 +856,8 @@ * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)$(INFIN)) ) * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) ) * ) + * + * Note: Not supported on windows */ real scalbn(real x, int n) { @@ -1113,6 +1115,8 @@ /*************************************** * Rounds x to the nearest integer value, using the current rounding * mode. + * + * Note: Not supported on windows */ long lrint(real x) { @@ -1134,6 +1138,8 @@ * * If the fractional part of x is exactly 0.5, the return value is rounded * away from zero. + * + * Note: Not supported on windows */ long lround(real x) { @@ -1169,6 +1175,8 @@ * $(TR $(TD anything) $(TD $(PLUSMN)0.0) $(TD $(NAN)) $(TD ?) $(TD yes)) * $(TR $(TD != $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)$(INFIN)) $(TD x) $(TD ?) $(TD no)) * ) + * + * Note: remquo not supported on windows */ real remainder(real x, real y) { return std.c.math.remainderl(x, y); } @@ -1428,6 +1436,8 @@ * the function result is infinite. The FE_INEXACT and FE_UNDERFLOW * exceptions will be raised if the function value is subnormal, and x is * not equal to y. + * + * Note: real nextafter(real, real) not supported on windows */ real nextafter(real x, real y) { diff -uNr dmd-1.024/dmd/src/phobos/std/process.d dmd-1.025/dmd/src/phobos/std/process.d --- dmd-1.024/dmd/src/phobos/std/process.d 2007-11-27 21:19:24.000000000 +0100 +++ dmd-1.025/dmd/src/phobos/std/process.d 2008-01-01 00:49:12.000000000 +0100 @@ -140,7 +140,11 @@ Lerror: retval = getErrno; - throw new Exception("Cannot spawn " ~ toString(pathname) ~ "; " ~ toString(strerror(retval)) ~ " [errno " ~ toString(retval) ~ "]"); + char[80] buf = void; + throw new Exception( + "Cannot spawn " ~ toString(pathname) ~ "; " + ~ toString(strerror_r(retval, buf.ptr, buf.length)) + ~ " [errno " ~ toString(retval) ~ "]"); } // _spawnvp private { diff -uNr dmd-1.024/dmd/src/phobos/std/socket.d dmd-1.025/dmd/src/phobos/std/socket.d --- dmd-1.024/dmd/src/phobos/std/socket.d 2007-11-27 21:19:24.000000000 +0100 +++ dmd-1.025/dmd/src/phobos/std/socket.d 2008-01-01 00:49:12.000000000 +0100 @@ -94,11 +94,9 @@ { if(errorCode > 0) { - char* cs; - size_t len; - - cs = strerror(errorCode); - len = strlen(cs); + char[80] buf; + auto cs = strerror_r(errorCode, buf.ptr, buf.length); + auto len = strlen(cs); if(cs[len - 1] == '\n') len--; diff -uNr dmd-1.024/dmd/src/phobos/std/stdio.d dmd-1.025/dmd/src/phobos/std/stdio.d --- dmd-1.024/dmd/src/phobos/std/stdio.d 2007-11-27 21:19:24.000000000 +0100 +++ dmd-1.025/dmd/src/phobos/std/stdio.d 2008-01-01 00:49:12.000000000 +0100 @@ -113,7 +113,15 @@ } this(uint errno) - { char* s = strerror(errno); + { + version (linux) + { char[80] buf = void; + auto s = std.string.strerror_r(errno, buf.ptr, buf.length); + } + else + { + auto s = std.string.strerror(errno); + } super(std.string.toString(s).dup); }