diff -uNr dmd-0.122/dmd/src/dmd/aggregate.h dmd-0.123/dmd/src/dmd/aggregate.h --- dmd-0.122/dmd/src/dmd/aggregate.h 2005-03-10 10:34:22.000000000 +0100 +++ dmd-0.123/dmd/src/dmd/aggregate.h 2005-05-06 21:28:54.000000000 +0200 @@ -162,6 +162,7 @@ Dsymbol *syntaxCopy(Dsymbol *s); void semantic(Scope *sc); void toCBuffer(OutBuffer *buf); + int isBaseOf2(ClassDeclaration *cd); #define OFFSET_RUNTIME 0x76543210 virtual int isBaseOf(ClassDeclaration *cd, int *poffset); diff -uNr dmd-0.122/dmd/src/dmd/class.c dmd-0.123/dmd/src/dmd/class.c --- dmd-0.122/dmd/src/dmd/class.c 2005-05-03 21:33:18.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/class.c 2005-05-08 16:42:44.000000000 +0200 @@ -57,7 +57,7 @@ vtblsym = NULL; vclassinfo = NULL; - if (id == Id::__sizeof) + if (id == Id::__sizeof || id == Id::alignof) error("illegal class name"); // BUG: What if this is the wrong ClassInfo, i.e. it is nested? @@ -493,6 +493,25 @@ } #endif +/********************************************* + * Determine if 'this' is a base class of cd. + * This is used to detect circular inheritance only. + */ + +int ClassDeclaration::isBaseOf2(ClassDeclaration *cd) +{ + if (!cd) + return 0; + //printf("ClassDeclaration::isBaseOf(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); + for (int i = 0; i < cd->baseclasses.dim; i++) + { BaseClass *b = (BaseClass *)cd->baseclasses.data[i]; + + if (b->base == this || isBaseOf2(b->base)) + return 1; + } + return 0; +} + /******************************************* * Determine if 'this' is a base class of cd. */ @@ -723,16 +742,16 @@ tc = NULL; if (!tc || !tc->sym->isInterfaceDeclaration()) { - error("base type must be interface, not %s", b->type->toChars()); + //error("base type must be interface, not %s", b->type->toChars()); baseclasses.remove(i); continue; } else { b->base = tc->sym; - if (b->base == this) + if (b->base == this || isBaseOf2(b->base)) { - error("base interface same as interface"); + error("circular inheritance of interface"); baseclasses.remove(i); continue; } @@ -740,7 +759,7 @@ { //error("forward reference of base class %s", baseClass->toChars()); // Forward reference of base, try again later - //printf("\ttry later, forward reference of base %s\n", baseClass->toChars()); + //printf("\ttry later, forward reference of base %s\n", b->base->toChars()); scope = scx ? scx : new Scope(*sc); scope->setNoFree(); scope->module->addDeferredSemantic(this); @@ -772,12 +791,17 @@ // Copy vtbl[] from base class if (b->base->vtblOffset()) { int d = b->base->vtbl.dim; - vtbl.reserve(d - 1); - for (int j = 1; j < d; j++) - vtbl.push(b->base->vtbl.data[j]); + if (d > 1) + { + vtbl.reserve(d - 1); + for (int j = 1; j < d; j++) + vtbl.push(b->base->vtbl.data[j]); + } } else + { vtbl.append(&b->base->vtbl); + } Lcontinue: ; @@ -828,6 +852,7 @@ { BaseClass *b = cd->interfaces[j]; + //printf("\tbase %s\n", b->base->toChars()); if (this == b->base) { //printf("\tfound at offset %d\n", b->offset); @@ -989,10 +1014,10 @@ void BaseClass::copyBaseInterfaces(Array *vtblInterfaces) { + //printf("+copyBaseInterfaces(), %s\n", base->toChars()); if (baseInterfaces_dim) - { error("circular inheritance of interface"); return; - } + baseInterfaces_dim = base->interfaces_dim; baseInterfaces = (BaseClass *)mem.calloc(baseInterfaces_dim, sizeof(BaseClass)); @@ -1009,4 +1034,5 @@ vtblInterfaces->push(b); // only need for M.I. b->copyBaseInterfaces(vtblInterfaces); } + //printf("-copyBaseInterfaces\n"); } diff -uNr dmd-0.122/dmd/src/dmd/constfold.c dmd-0.123/dmd/src/dmd/constfold.c --- dmd-0.122/dmd/src/dmd/constfold.c 2005-05-03 15:07:08.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/constfold.c 2005-05-11 01:12:38.000000000 +0200 @@ -120,7 +120,12 @@ if (tb->ty == Tbit) return new IntegerExp(loc, e1->toInteger() != 0, type); if (type->isintegral()) - return new IntegerExp(loc, e1->toInteger(), type); + { + if (type->isunsigned()) + return new IntegerExp(loc, e1->toUInteger(), type); + else + return new IntegerExp(loc, e1->toInteger(), type); + } if (tb->isreal()) { real_t value = e1->toReal(); @@ -375,25 +380,37 @@ switch (e1->type->toBasetype()->ty) { case Tint8: - case Tuns8: value = (d_int8)(value) >> count; break; + case Tuns8: + value = (d_uns8)(value) >> count; + break; + case Tint16: - case Tuns16: value = (d_int16)(value) >> count; break; + case Tuns16: + value = (d_uns16)(value) >> count; + break; + case Tint32: - case Tuns32: value = (d_int32)(value) >> count; break; + case Tuns32: + value = (d_uns32)(value) >> count; + break; + case Tint64: - case Tuns64: value = (d_int64)(value) >> count; break; + case Tuns64: + value = (d_uns64)(value) >> count; + break; + default: assert(0); } diff -uNr dmd-0.122/dmd/src/dmd/declaration.c dmd-0.123/dmd/src/dmd/declaration.c --- dmd-0.122/dmd/src/dmd/declaration.c 2005-04-24 11:21:40.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/declaration.c 2005-05-08 15:53:42.000000000 +0200 @@ -204,6 +204,9 @@ } this->inSemantic = 1; + if (storage_class & STCconst) + error("cannot be const"); + storage_class |= sc->stc & STCdeprecated; // Given: @@ -653,7 +656,7 @@ cd; cd = cd->baseClass) { - if (cd->dtor) + //if (cd->dtor) { FuncDeclaration *fd; Expression *efd; Expression *ec; diff -uNr dmd-0.122/dmd/src/dmd/dsymbol.c dmd-0.123/dmd/src/dmd/dsymbol.c --- dmd-0.122/dmd/src/dmd/dsymbol.c 2005-04-25 10:53:28.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/dsymbol.c 2005-05-08 16:43:26.000000000 +0200 @@ -279,8 +279,8 @@ } if (sd->isAggregateDeclaration() || sd->isEnumDeclaration()) { - if (ident == Id::__sizeof) - error(".sizeof property cannot be redefined"); + if (ident == Id::__sizeof || ident == Id::alignof) + error(".%s property cannot be redefined", ident->toChars()); } } } diff -uNr dmd-0.122/dmd/src/dmd/enum.c dmd-0.123/dmd/src/dmd/enum.c --- dmd-0.122/dmd/src/dmd/enum.c 2005-02-09 14:44:24.000000000 +0100 +++ dmd-0.123/dmd/src/dmd/enum.c 2005-05-09 17:47:08.000000000 +0200 @@ -17,13 +17,14 @@ /********************************* EnumDeclaration ****************************/ -EnumDeclaration::EnumDeclaration(Identifier *id, Type *memtype) +EnumDeclaration::EnumDeclaration(Loc loc, Identifier *id, Type *memtype) : ScopeDsymbol(id) { + this->loc = loc; type = new TypeEnum(this); this->memtype = memtype; maxval = 0; - minval = 0x7FFFFFFF; // BUG: long long max? + minval = 0; defaultval = 0; } @@ -39,14 +40,14 @@ ed->memtype = t; } else - ed = new EnumDeclaration(ident, t); + ed = new EnumDeclaration(loc, ident, t); ScopeDsymbol::syntaxCopy(ed); return ed; } void EnumDeclaration::semantic(Scope *sc) { int i; - integer_t number; + uinteger_t number; Type *t; Scope *sce; @@ -58,7 +59,7 @@ parent = sc->scopesym; memtype = memtype->semantic(loc, sc); if (!memtype->isintegral()) - error("EnumBaseType must be integral type, not %s", memtype->toChars()); + error("base type must be of integral type, not %s", memtype->toChars()); t = isAnonymous() ? memtype : type; symtab = new DsymbolTable(); @@ -69,6 +70,7 @@ return; if (members->dim == 0) error("enum %s must have at least one member", toChars()); + int first = 1; for (i = 0; i < members->dim; i++) { EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember(); @@ -106,15 +108,30 @@ else em->addMember(this); - if (number < minval) + if (first) + { first = 0; + defaultval = number; minval = number; - if (number > maxval) maxval = number; - if (i == 0) - defaultval = number; + } + else if (memtype->isunsigned()) + { + if (number < minval) + minval = number; + if (number > maxval) + maxval = number; + } + else + { + if ((sinteger_t)number < (sinteger_t)minval) + minval = number; + if ((sinteger_t)number > (sinteger_t)maxval) + maxval = number; + } number++; } + //printf("defaultval = %lld\n", defaultval); sce->pop(); //members->print(); diff -uNr dmd-0.122/dmd/src/dmd/enum.h dmd-0.123/dmd/src/dmd/enum.h --- dmd-0.122/dmd/src/dmd/enum.h 2004-12-30 01:17:04.000000000 +0100 +++ dmd-0.123/dmd/src/dmd/enum.h 2005-05-09 15:51:16.000000000 +0200 @@ -29,7 +29,7 @@ integer_t minval; integer_t defaultval; // default initializer - EnumDeclaration(Identifier *id, Type *memtype); + EnumDeclaration(Loc loc, Identifier *id, Type *memtype); Dsymbol *syntaxCopy(Dsymbol *s); void semantic(Scope *sc); Dsymbol *oneMember(); diff -uNr dmd-0.122/dmd/src/dmd/expression.c dmd-0.123/dmd/src/dmd/expression.c --- dmd-0.122/dmd/src/dmd/expression.c 2005-05-03 15:08:06.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/expression.c 2005-05-11 12:21:42.000000000 +0200 @@ -396,6 +396,12 @@ return 0; } +uinteger_t Expression::toUInteger() +{ + //printf("Expression %s\n", Token::toChars(op)); + return (uinteger_t)toInteger(); +} + real_t Expression::toReal() { error("Floating point constant expression expected instead of %s", toChars()); @@ -676,6 +682,11 @@ return (real_t) 0; } +complex_t IntegerExp::toComplex() +{ + return toReal(); +} + int IntegerExp::isBool(int result) { return result ? value != 0 : value == 0; @@ -707,7 +718,7 @@ e = this; else if (!loc.filename) loc = e->loc; - error("constant %s is not an lvalue", e->toChars()); + e->error("constant %s is not an lvalue", e->toChars()); return this; } @@ -748,7 +759,12 @@ integer_t RealExp::toInteger() { - return (integer_t) value; + return (sinteger_t) value; +} + +uinteger_t RealExp::toUInteger() +{ + return (uinteger_t) value; } real_t RealExp::toReal() @@ -871,7 +887,12 @@ integer_t ComplexExp::toInteger() { - return (integer_t) value; + return (sinteger_t) value; +} + +uinteger_t ComplexExp::toUInteger() +{ + return (uinteger_t) value; } real_t ComplexExp::toReal() @@ -4190,14 +4211,14 @@ } else { - typeCombine(); type = e1->type; + typeCombine(); e1->checkArithmetic(); e2->checkArithmetic(); if (type->isreal() || type->isimaginary()) { assert(global.errors || e2->type->isfloating()); - e2 = e2->castTo(type); + e2 = e2->castTo(e1->type); } e = this; } @@ -4231,14 +4252,14 @@ e = scaleFactor(); else { - typeCombine(); type = e1->type; + typeCombine(); e1->checkArithmetic(); e2->checkArithmetic(); if (type->isreal() || type->isimaginary()) { assert(e2->type->isfloating()); - e2 = e2->castTo(type); + e2 = e2->castTo(e1->type); } e = this; } @@ -4384,7 +4405,16 @@ Type *t2; t1 = e1->type; - if (t1->isreal() || t1->isimaginary()) + if (t1->isreal()) + { // x/iv = i(-x/v) + // Therefore, the result is 0 + e2 = new CommaExp(loc, e2, new RealExp(loc, 0, t1)); + e2->type = t1; + e = new AssignExp(loc, e1, e2); + e->type = t1; + return e; + } + else if (t1->isimaginary()) { Expression *e; switch (t1->ty) @@ -4712,12 +4742,6 @@ Type *tb1 = e1->type->toBasetype(); Type *tb2 = e2->type->toBasetype(); -#if 0 - if (tb1->ty == Tsarray) - e1 = e1->castTo(tb1->next->arrayOf()); - if (tb2->ty == Tsarray) - e2 = e2->castTo(tb2->next->arrayOf()); -#endif /* BUG: Should handle things like: * char c; @@ -4725,7 +4749,25 @@ * ' ' ~ c; */ +#if 0 + e1->type->print(); + e2->type->print(); +#endif + if ((tb1->ty == Tsarray || tb1->ty == Tarray) && + e2->type->equals(tb1->next)) + { + type = tb1->next->arrayOf(); + return this; + } + else if ((tb2->ty == Tsarray || tb2->ty == Tarray) && + e1->type->equals(tb2->next)) + { + type = tb2->next->arrayOf(); + return this; + } + typeCombine(); + if (type->toBasetype()->ty == Tsarray) type = type->toBasetype()->next->arrayOf(); #if 0 @@ -5212,11 +5254,13 @@ error("need member function opCmp() for struct %s to compare", t1->toChars()); e = this; } +#if 0 else if (t1->iscomplex() || t2->iscomplex()) { error("compare not defined for complex operands"); e = new IntegerExp(0); } +#endif else e = this; return e; diff -uNr dmd-0.122/dmd/src/dmd/expression.h dmd-0.123/dmd/src/dmd/expression.h --- dmd-0.122/dmd/src/dmd/expression.h 2005-04-12 23:18:44.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/expression.h 2005-05-09 16:53:06.000000000 +0200 @@ -67,6 +67,7 @@ static Array *arraySyntaxCopy(Array *exps); virtual integer_t toInteger(); + virtual uinteger_t toUInteger(); virtual real_t toReal(); virtual real_t toImaginary(); virtual complex_t toComplex(); @@ -122,6 +123,7 @@ integer_t toInteger(); real_t toReal(); real_t toImaginary(); + complex_t toComplex(); int isConst(); int isBool(int result); int implicitConvTo(Type *t); @@ -139,6 +141,7 @@ Expression *semantic(Scope *sc); char *toChars(); integer_t toInteger(); + uinteger_t toUInteger(); real_t toReal(); real_t toImaginary(); complex_t toComplex(); @@ -175,6 +178,7 @@ Expression *semantic(Scope *sc); char *toChars(); integer_t toInteger(); + uinteger_t toUInteger(); real_t toReal(); real_t toImaginary(); complex_t toComplex(); diff -uNr dmd-0.122/dmd/src/dmd/func.c dmd-0.123/dmd/src/dmd/func.c --- dmd-0.122/dmd/src/dmd/func.c 2005-05-02 22:17:26.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/func.c 2005-05-05 20:27:56.000000000 +0200 @@ -1044,7 +1044,6 @@ error(loc, "%s does not match argument types (%s)", Argument::argsTypesToChars(tf->arguments, tf->varargs), buf.toChars()); -*(char*)0=0; return m.anyf; // as long as it's not a FuncAliasDeclaration } else diff -uNr dmd-0.122/dmd/src/dmd/lexer.c dmd-0.123/dmd/src/dmd/lexer.c --- dmd-0.122/dmd/src/dmd/lexer.c 2005-04-24 22:55:46.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/lexer.c 2005-05-10 14:53:18.000000000 +0200 @@ -242,6 +242,26 @@ fatal(); } +void Lexer::error(Loc loc, const char *format, ...) +{ + char *p = loc.toChars(); + if (*p) + printf("%s: ", p); + mem.free(p); + + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + + printf("\n"); + fflush(stdout); + + global.errors++; + if (global.errors > 20) // moderate blizzard of cascading messages + fatal(); +} + TOK Lexer::nextToken() { Token *t; @@ -1875,15 +1895,17 @@ Token tok; int linnum; char *filespec = NULL; + Loc loc = this->loc; scan(&tok); if (tok.value != TOKidentifier || tok.ident != Id::line) goto Lerr; scan(&tok); - if (tok.value != TOKint32v) + if (tok.value == TOKint32v || tok.value == TOKint64v) + linnum = tok.uns64value - 1; + else goto Lerr; - linnum = tok.uns64value - 1; while (1) { @@ -1913,6 +1935,14 @@ p++; continue; // skip white space + case '_': + if (memcmp(p, "__FILE__", 8) == 0) + { + p += 8; + filespec = mem.strdup(loc.filename ? loc.filename : mod->ident->toChars()); + } + continue; + case '"': if (filespec) goto Lerr; @@ -1961,7 +1991,7 @@ } Lerr: - error("#line integer [\"filespec\"]\\n expected"); + error(loc, "#line integer [\"filespec\"]\\n expected"); } diff -uNr dmd-0.122/dmd/src/dmd/lexer.h dmd-0.123/dmd/src/dmd/lexer.h --- dmd-0.122/dmd/src/dmd/lexer.h 2005-03-18 19:53:20.000000000 +0100 +++ dmd-0.123/dmd/src/dmd/lexer.h 2005-05-10 14:37:26.000000000 +0200 @@ -240,6 +240,7 @@ TOK number(Token *t); TOK inreal(Token *t); void error(const char *format, ...); + void error(Loc loc, const char *format, ...); void pragma(); unsigned decodeUTF(); }; diff -uNr dmd-0.122/dmd/src/dmd/mars.c dmd-0.123/dmd/src/dmd/mars.c --- dmd-0.122/dmd/src/dmd/mars.c 2005-04-24 01:34:02.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/mars.c 2005-05-10 14:17:08.000000000 +0200 @@ -49,7 +49,7 @@ copyright = "Copyright (c) 1999-2005 by Digital Mars"; written = "written by Walter Bright"; - version = "v0.122"; + version = "v0.123"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); @@ -521,7 +521,7 @@ if (global.params.verbose) printf("parse %s\n", m->toChars()); m->deleteObjFile(); - m->read(); + m->read(0); m->parse(); } if (global.errors) diff -uNr dmd-0.122/dmd/src/dmd/mars.h dmd-0.123/dmd/src/dmd/mars.h --- dmd-0.122/dmd/src/dmd/mars.h 2005-04-27 01:14:06.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/mars.h 2005-05-09 16:48:50.000000000 +0200 @@ -105,7 +105,13 @@ #endif #endif +// Be careful not to care about sign with integer_t typedef unsigned long long integer_t; + +// Signed and unsigned variants +typedef long long sinteger_t; +typedef unsigned long long uinteger_t; + typedef long double real_t; typedef signed char d_int8; diff -uNr dmd-0.122/dmd/src/dmd/module.c dmd-0.123/dmd/src/dmd/module.c --- dmd-0.122/dmd/src/dmd/module.c 2005-04-06 23:13:56.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/module.c 2005-05-10 14:20:08.000000000 +0200 @@ -160,16 +160,19 @@ // BUG: the sym file is actually a source file that is // parsed. Someday make it a real symbol table m->srcfile = m->symfile; - m->read(); + m->read(loc); m->parse(); return m; } -void Module::read() +void Module::read(Loc loc) { //printf("Module::read('%s') file '%s'\n", toChars(), srcfile->toChars()); - srcfile->readv(); + if (srcfile->read()) + { error(loc, "cannot read file '%s'", srcfile->toChars()); + fatal(); + } } inline unsigned readwordLE(unsigned short *p) diff -uNr dmd-0.122/dmd/src/dmd/module.h dmd-0.123/dmd/src/dmd/module.h --- dmd-0.122/dmd/src/dmd/module.h 2004-12-18 16:12:24.000000000 +0100 +++ dmd-0.123/dmd/src/dmd/module.h 2005-05-10 14:16:48.000000000 +0200 @@ -83,7 +83,7 @@ static Module *load(Loc loc, Array *packages, Identifier *ident); char *kind(); - void read(); // read file + void read(Loc loc); // read file void parse(); // syntactic parse void semantic(); // semantic analysis void semantic2(); // pass 2 semantic analysis diff -uNr dmd-0.122/dmd/src/dmd/mtype.c dmd-0.123/dmd/src/dmd/mtype.c --- dmd-0.122/dmd/src/dmd/mtype.c 2005-04-27 01:21:44.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/mtype.c 2005-05-09 17:47:28.000000000 +0200 @@ -1489,6 +1489,7 @@ { //printf("TypeSArray::semantic() %s\n", toChars()); next = next->semantic(loc,sc); + Type *tbn = next->toBasetype(); if (dim) { integer_t n, n2; @@ -1501,23 +1502,26 @@ if (d1 != d2) goto Loverflow; - if (next->ty == Tbit && (d2 + 31) < d2) + + if (tbn->ty == Tbit && (d2 + 31) < d2) goto Loverflow; - else if (next->isintegral() || - next->isfloating() || - next->ty == Tpointer || - next->ty == Tarray || - next->ty == Tsarray || - next->ty == Taarray || - next->ty == Tclass) + else if (tbn->isintegral() || + tbn->isfloating() || + tbn->ty == Tpointer || + tbn->ty == Tarray || + tbn->ty == Tsarray || + tbn->ty == Taarray || + tbn->ty == Tclass) { /* Only do this for types that don't need to have semantic() * run on them for the size, since they may be forward referenced. */ - n = next->size(loc); + n = tbn->size(loc); n2 = n * d2; if ((int)n2 < 0) goto Loverflow; + if (n2 >= 0x1000000) // put a 'reasonable' limit on it + goto Loverflow; if (n && n2 / n != d2) { Loverflow: @@ -1526,15 +1530,15 @@ } } } - switch (next->ty) + switch (tbn->ty) { case Tfunction: case Tnone: - error(loc, "can't have array of %s", next->toChars()); + error(loc, "can't have array of %s", tbn->toChars()); break; } - if (next->isauto()) - error(loc, "cannot have array of auto %s", next->toChars()); + if (tbn->isauto()) + error(loc, "cannot have array of auto %s", tbn->toChars()); return merge(); } @@ -3199,6 +3203,10 @@ { e = new IntegerExp(0, sym->minval, this); } + else if (ident == Id::init) + { + e = defaultInit(); + } else { assert(sym->memtype); diff -uNr dmd-0.122/dmd/src/dmd/parse.c dmd-0.123/dmd/src/dmd/parse.c --- dmd-0.122/dmd/src/dmd/parse.c 2005-04-25 10:50:04.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/parse.c 2005-05-09 15:53:20.000000000 +0200 @@ -844,6 +844,7 @@ { EnumDeclaration *e; Identifier *id; Type *t; + Loc loc = this->loc; //printf("Parser::parseEnum()\n"); nextToken(); @@ -862,7 +863,7 @@ else t = NULL; - e = new EnumDeclaration(id, t); + e = new EnumDeclaration(loc, id, t); if (token.value == TOKsemicolon && id) nextToken(); else if (token.value == TOKlcurly) diff -uNr dmd-0.122/dmd/src/dmd/statement.c dmd-0.123/dmd/src/dmd/statement.c --- dmd-0.122/dmd/src/dmd/statement.c 2005-05-02 22:33:06.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/statement.c 2005-05-10 02:13:58.000000000 +0200 @@ -623,7 +623,8 @@ int ForStatement::fallOffEnd() { - body->fallOffEnd(); + if (body) + body->fallOffEnd(); return TRUE; } @@ -969,7 +970,8 @@ int ForeachStatement::fallOffEnd() { - body->fallOffEnd(); + if (body) + body->fallOffEnd(); return TRUE; } diff -uNr dmd-0.122/dmd/src/dmd/template.c dmd-0.123/dmd/src/dmd/template.c --- dmd-0.122/dmd/src/dmd/template.c 2005-04-14 22:01:14.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/template.c 2005-05-09 22:02:30.000000000 +0200 @@ -2043,6 +2043,7 @@ #if LOG printf("\tdo semantic\n"); #endif + // Run semantic on each argument, place results in tiargs[] semanticTiargs(sc); @@ -2135,6 +2136,50 @@ inst = this; parent = sc->parent; + /* Detect recursive mixin instantiations. + */ + for (Dsymbol *s = parent; s; s = s->parent) + { + //printf("\ts = '%s'\n", s->toChars()); + TemplateMixin *tm = s->isTemplateMixin(); + if (!tm || tempdecl != tm->tempdecl) + continue; + + for (int i = 0; i < tiargs->dim; i++) + { Object *o = (Object *)tiargs->data[i]; + Type *ta = isType(o); + Expression *ea = isExpression(o); + Dsymbol *sa = isDsymbol(o); + Object *tmo = (Object *)tm->tiargs->data[i]; + if (ta) + { + Type *tmta = isType(tmo); + if (!tmta) + goto Lcontinue; + if (!ta->equals(tmta)) + goto Lcontinue; + } + else if (ea) + { Expression *tme = isExpression(tmo); + if (!tme || !ea->equals(tme)) + goto Lcontinue; + } + else if (sa) + { + Dsymbol *tmsa = isDsymbol(tmo); + if (sa != tmsa) + goto Lcontinue; + } + else + assert(0); + } + error("recursive mixin instantiation"); + return; + + Lcontinue: + continue; + } + // Copy the syntax trees from the TemplateDeclaration members = Dsymbol::arraySyntaxCopy(tempdecl->members); if (!members) diff -uNr dmd-0.122/dmd/src/dmd/todt.c dmd-0.123/dmd/src/dmd/todt.c --- dmd-0.122/dmd/src/dmd/todt.c 2005-04-27 01:23:24.000000000 +0200 +++ dmd-0.123/dmd/src/dmd/todt.c 2005-05-11 00:48:02.000000000 +0200 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2002 by Digital Mars +// Copyright (c) 1999-2005 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -186,6 +186,8 @@ length++; } + Expression *edefault = tb->next->defaultInit(); + d = NULL; pdtend = &d; for (i = 0; i < dim; i++) @@ -194,7 +196,7 @@ if (dt) pdtend = dtcat(pdtend, dt); else - pdtend = tn->toDt(pdtend); + pdtend = edefault->toDt(pdtend); } switch (tb->ty) { @@ -204,7 +206,16 @@ tadim = ta->dim->toInteger(); if (dim < tadim) - pdtend = dtnzeros(pdtend, size * (tadim - dim)); // pad out end of array + { + if (edefault->isBool(FALSE)) + // pad out end of array + pdtend = dtnzeros(pdtend, size * (tadim - dim)); + else + { + for (i = dim; i < tadim; i++) + pdtend = edefault->toDt(pdtend); + } + } else if (dim > tadim) error("too many initializers %d for array[%d]", dim, tadim); break; @@ -353,7 +364,9 @@ dt_t **Expression::toDt(dt_t **pdt) { - //printf("Expression::toDt() %d\n", op); +#ifdef DEBUG + printf("Expression::toDt() %d\n", op); +#endif error("non-constant expression %s", toChars()); pdt = dtnzeros(pdt, 1); return pdt; @@ -522,7 +535,11 @@ //printf("SymOffExp::toDt('%s')\n", var->toChars()); assert(var); if (!(var->isDataseg() || var->isCodeseg()) || var->needThis()) - { error("non-constant expression %s", toChars()); + { +#ifdef DEBUG + printf("SymOffExp::toDt()\n"); +#endif + error("non-constant expression %s", toChars()); return pdt; } s = var->toSymbol(); @@ -541,6 +558,9 @@ *pdtend = v->init->toDt(); return pdt; } +#ifdef DEBUG + printf("VarExp::toDt() %d\n", op); +#endif error("non-constant expression %s", toChars()); pdt = dtnzeros(pdt, 1); return pdt; @@ -592,7 +612,7 @@ VarDeclaration *v = (VarDeclaration *)fields.data[i]; Initializer *init; - //printf("\t\tv->offset = %d, offset = %d\n", v->offset, offset); + //printf("\t\tv = '%s' v->offset = %2d, offset = %2d\n", v->toChars(), v->offset, offset); dt = NULL; init = v->init; if (init) @@ -600,7 +620,9 @@ dt = init->toDt(); } else if (v->offset >= offset) + { //printf("\t\tdefault initializer\n"); v->type->toDt(&dt); + } if (dt) { if (v->offset < offset) @@ -706,39 +728,50 @@ int i; unsigned len; + //printf("TypeSArray::toDt()\n"); len = dim->toInteger(); if (len) { while (*pdt) pdt = &((*pdt)->DTnext); - if (next->toBasetype()->ty == Tbit) + Expression *e = next->defaultInit(); + Type *tbn = next->toBasetype(); + if (tbn->ty == Tbit) { Bits databits; databits.resize(len); - if (next->defaultInit()->toInteger()) + if (e->toInteger()) databits.set(); pdt = dtnbytes(pdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data); } else { - next->toDt(pdt); + if (tbn->ty == Tstruct) + next->toDt(pdt); + else + e->toDt(pdt); dt_optimize(*pdt); if ((*pdt)->dt == DT_azeros && !(*pdt)->DTnext) { (*pdt)->DTazeros *= len; + pdt = &((*pdt)->DTnext); } else if ((*pdt)->dt == DT_1byte && (*pdt)->DTonebyte == 0 && !(*pdt)->DTnext) { (*pdt)->dt = DT_azeros; (*pdt)->DTazeros = len; + pdt = &((*pdt)->DTnext); } else { for (i = 1; i < len; i++) { - pdt = next->toDt(pdt); + if (tbn->ty == Tstruct) + pdt = next->toDt(pdt); + else + pdt = e->toDt(pdt); } } } diff -uNr dmd-0.122/dmd/src/dmd/toobj.c dmd-0.123/dmd/src/dmd/toobj.c --- dmd-0.122/dmd/src/dmd/toobj.c 2005-03-16 13:32:44.000000000 +0100 +++ dmd-0.123/dmd/src/dmd/toobj.c 2005-05-05 18:25:06.000000000 +0200 @@ -595,7 +595,10 @@ //printf("InterfaceDeclaration::toObjFile('%s')\n", toChars()); - if (members && global.params.symdebug) + if (!members) + return; + + if (global.params.symdebug) toDebug(); if (parent && parent->isTemplateInstance()) diff -uNr dmd-0.122/dmd/src/phobos/internal/adi.d dmd-0.123/dmd/src/phobos/internal/adi.d --- dmd-0.122/dmd/src/phobos/internal/adi.d 2005-05-04 12:26:36.000000000 +0200 +++ dmd-0.123/dmd/src/phobos/internal/adi.d 2005-05-11 14:55:04.000000000 +0200 @@ -58,8 +58,10 @@ { char clo = *lo; char chi = *hi; + //printf("lo = %d, hi = %d\n", lo, hi); if (clo <= 0x7F && chi <= 0x7F) { + //printf("\tascii\n"); *lo = chi; *hi = clo; lo++; @@ -79,6 +81,7 @@ if (lo == hi) break; + //printf("\tstridelo = %d, stridehi = %d\n", stridelo, stridehi); if (stridelo == stridehi) { @@ -86,7 +89,7 @@ memcpy(lo, hi, stridelo); memcpy(hi, tmp, stridelo); lo += stridelo; - hi -= stridehi; + hi--; continue; } @@ -99,7 +102,7 @@ memcpy(lo, tmp, stridehi); lo += stridehi; - hi -= stridelo; + hi = hi - 1 + (stridehi - stridelo); } } return *cast(long*)(&a); @@ -177,7 +180,7 @@ *cast(int*)lo = *cast(int*)hi; *cast(int*)hi = tmp; lo += stridelo; - hi -= stridehi; + hi--; continue; } @@ -189,7 +192,7 @@ memcpy(lo, tmp, stridehi * wchar.sizeof); lo += stridehi; - hi -= stridelo; + hi = hi - 1 + (stridehi - stridelo); } } return *cast(long*)(&a); diff -uNr dmd-0.122/dmd/src/phobos/internal/arraycat.d dmd-0.123/dmd/src/phobos/internal/arraycat.d --- dmd-0.122/dmd/src/phobos/internal/arraycat.d 2005-05-04 12:26:36.000000000 +0200 +++ dmd-0.123/dmd/src/phobos/internal/arraycat.d 2005-05-11 14:55:04.000000000 +0200 @@ -69,6 +69,7 @@ uint a_length; uint x_bytes; + //printf("_d_arraycatb(x.ptr = %p, x.length = %d, y.ptr = %p, y.length = %d)\n", x.ptr, x.length, y.ptr, y.length); if (!x.length) return y; if (!y.length) @@ -170,6 +171,7 @@ memset(ba.ptr, val, len >> 3); for (uint i = len & ~7; i < len; i++) ba[i] = value; + //printf("-_d_arraysetbit2(ba.ptr = %p, ba.length = %d, value = %d)\n", ba.ptr, ba.length, ba[0]); return ba; } diff -uNr dmd-0.122/dmd/src/phobos/internal/memset.d dmd-0.123/dmd/src/phobos/internal/memset.d --- dmd-0.122/dmd/src/phobos/internal/memset.d 2005-05-04 12:26:36.000000000 +0200 +++ dmd-0.123/dmd/src/phobos/internal/memset.d 2005-05-11 14:55:04.000000000 +0200 @@ -76,6 +76,16 @@ return pstart; } +cdouble *_memset128(cdouble *p, cdouble value, int count) +{ + cdouble *pstart = p; + cdouble *ptop; + + for (ptop = &p[count]; p < ptop; p++) + *p = value; + return pstart; +} + real *_memset80(real *p, real value, int count) { real *pstart = p; @@ -86,6 +96,16 @@ return pstart; } +creal *_memset160(creal *p, creal value, int count) +{ + creal *pstart = p; + creal *ptop; + + for (ptop = &p[count]; p < ptop; p++) + *p = value; + return pstart; +} + void *_memsetn(void *p, void *value, int count, int sizelem) { void *pstart = p; int i; diff -uNr dmd-0.122/dmd/src/phobos/std/typeinfo/ti_void.d dmd-0.123/dmd/src/phobos/std/typeinfo/ti_void.d --- dmd-0.122/dmd/src/phobos/std/typeinfo/ti_void.d 2005-05-04 12:26:36.000000000 +0200 +++ dmd-0.123/dmd/src/phobos/std/typeinfo/ti_void.d 2005-05-11 14:55:04.000000000 +0200 @@ -25,8 +25,7 @@ int tsize() { - assert(0); - return byte.sizeof; + return void.sizeof; } void swap(void *p1, void *p2)