From 6d22dd799905a309de951eab1720e93c917df142 Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Mon, 8 Nov 2010 16:55:35 +0300 Subject: [PATCH] Updated to 2.050 --- dmd2/arrayop.c | 25 ++++++++++ dmd2/declaration.c | 32 +++++++----- dmd2/declaration.h | 4 +- dmd2/expression.c | 52 ++++++++++++++++--- dmd2/expression.h | 1 + dmd2/func.c | 57 ++++++++++++++++++--- dmd2/idgen.c | 7 ++- dmd2/interpret.c | 29 +++++++---- dmd2/mars.c | 5 +- dmd2/mtype.c | 111 +++++++++++++++++++++++++++++++++++------ dmd2/mtype.h | 12 ++++- dmd2/opover.c | 35 +++++++------ dmd2/optimize.c | 10 +++- dmd2/parse.c | 78 +++++++++++++++++++---------- dmd2/statement.c | 10 +++- dmd2/staticassert.c | 5 +- dmd2/struct.c | 7 ++- dmd2/template.c | 1 + druntime.patch | 97 ++++++++++------------------------- gen/toir.cpp | 11 ++-- gen/tollvm.cpp | 4 ++ gen/typinf.cpp | 5 +- ir/irstruct.cpp | 3 +- phobos.patch | 46 ++++++++--------- runtime/CMakeLists.txt | 1 + 25 files changed, 447 insertions(+), 201 deletions(-) diff --git a/dmd2/arrayop.c b/dmd2/arrayop.c index e794070b..92985f39 100644 --- a/dmd2/arrayop.c +++ b/dmd2/arrayop.c @@ -55,7 +55,19 @@ bool isArrayOpValid(Expression *e) case TOKxor: case TOKand: case TOKor: + case TOKassign: + case TOKaddass: + case TOKminass: + case TOKmulass: + case TOKdivass: + case TOKmodass: + case TOKxorass: + case TOKandass: + case TOKorass: +#if DMDV2 case TOKpow: + case TOKpowass: +#endif return isArrayOpValid(((BinExp *)e)->e1) && isArrayOpValid(((BinExp *)e)->e2); case TOKcall: @@ -607,6 +619,19 @@ int Expression::isArrayOperand() case TOKxor: case TOKand: case TOKor: + case TOKassign: + case TOKaddass: + case TOKminass: + case TOKmulass: + case TOKdivass: + case TOKmodass: + case TOKxorass: + case TOKandass: + case TOKorass: +#if DMDV2 + case TOKpow: + case TOKpowass: +#endif case TOKneg: case TOKtilde: return 1; diff --git a/dmd2/declaration.c b/dmd2/declaration.c index 4cb6c42e..9a143da3 100644 --- a/dmd2/declaration.c +++ b/dmd2/declaration.c @@ -1321,25 +1321,31 @@ Lagain: } else if (ei) { - if (isDataseg()) - /* static const/invariant does CTFE - */ + if (isDataseg() || (storage_class & STCmanifest)) e = e->optimize(WANTvalue | WANTinterpret); else e = e->optimize(WANTvalue); - if (e->op == TOKint64 || e->op == TOKstring || e->op == TOKfloat64) + switch (e->op) { - ei->exp = e; // no errors, keep result - } + case TOKint64: + case TOKfloat64: + case TOKstring: + case TOKarrayliteral: + case TOKassocarrayliteral: + case TOKstructliteral: + case TOKnull: + ei->exp = e; // no errors, keep result + break; + + default: #if DMDV2 - else - { - /* Save scope for later use, to try again - */ - scope = new Scope(*sc); - scope->setNoFree(); - } + /* Save scope for later use, to try again + */ + scope = new Scope(*sc); + scope->setNoFree(); #endif + break; + } } else init = i2; // no errors, keep result diff --git a/dmd2/declaration.h b/dmd2/declaration.h index 0362d15d..e7c8f920 100644 --- a/dmd2/declaration.h +++ b/dmd2/declaration.h @@ -49,6 +49,7 @@ enum PROT; enum LINK; enum TOK; enum MATCH; +enum PURE; #define STCundefined 0LL #define STCstatic 1LL @@ -697,6 +698,7 @@ struct FuncDeclaration : Declaration #if IN_GCC VarDeclaration *v_argptr; // '_argptr' variable #endif + VarDeclaration *v_argsave; // save area for args passed in registers for variadic functions Dsymbols *parameters; // Array of VarDeclaration's for parameters DsymbolTable *labtab; // statement label symbol table Declaration *overnext; // next in overload list @@ -776,7 +778,7 @@ struct FuncDeclaration : Declaration int isAbstract(); int isCodeseg(); int isOverloadable(); - int isPure(); + enum PURE isPure(); int isSafe(); int isTrusted(); virtual int isNested(); diff --git a/dmd2/expression.c b/dmd2/expression.c index a9074925..86f7f5d5 100644 --- a/dmd2/expression.c +++ b/dmd2/expression.c @@ -5619,6 +5619,11 @@ Expression *CompileExp::semantic(Scope *sc) #endif UnaExp::semantic(sc); e1 = resolveProperties(sc, e1); + if (!e1->type->isString()) + { + error("argument to mixin must be a string type, not %s\n", e1->type->toChars()); + return new ErrorExp(); + } e1 = e1->optimize(WANTvalue | WANTinterpret); if (e1->op != TOKstring) { error("argument to mixin must be a string, not (%s)", e1->toChars()); @@ -5749,7 +5754,8 @@ Expression *AssertExp::semantic(Scope *sc) if (e1->isBool(FALSE)) { FuncDeclaration *fd = sc->parent->isFuncDeclaration(); - fd->hasReturnExp |= 4; + if (fd) + fd->hasReturnExp |= 4; if (!global.params.useAssert) { Expression *e = new HaltExp(loc); @@ -7135,7 +7141,7 @@ Lagain: { TypeDelegate *td = (TypeDelegate *)t1; assert(td->next->ty == Tfunction); tf = (TypeFunction *)(td->next); - if (sc->func && sc->func->isPure() && !tf->ispure) + if (sc->func && sc->func->isPure() && !tf->purity) { error("pure function '%s' cannot call impure delegate '%s'", sc->func->toChars(), e1->toChars()); } @@ -7149,7 +7155,7 @@ Lagain: { Expression *e = new PtrExp(loc, e1); t1 = ((TypePointer *)t1)->next; - if (sc->func && sc->func->isPure() && !((TypeFunction *)t1)->ispure) + if (sc->func && sc->func->isPure() && !((TypeFunction *)t1)->purity) { error("pure function '%s' cannot call impure function pointer '%s'", sc->func->toChars(), e1->toChars()); } @@ -7272,9 +7278,9 @@ int CallExp::checkSideEffect(int flag) * then this expression has no side effects. */ Type *t = e1->type->toBasetype(); - if (t->ty == Tfunction && ((TypeFunction *)t)->ispure) + if (t->ty == Tfunction && ((TypeFunction *)t)->purity) return 0; - if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->ispure) + if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->purity) return 0; #endif return 1; @@ -8111,6 +8117,8 @@ Expression *SliceExp::semantic(Scope *sc) goto Lerror; } } + else if (t == Type::terror) + goto Lerr; else goto Lerror; @@ -8145,8 +8153,8 @@ Expression *SliceExp::semantic(Scope *sc) if (t->ty == Ttuple) { - lwr = lwr->optimize(WANTvalue); - upr = upr->optimize(WANTvalue); + lwr = lwr->optimize(WANTvalue | WANTinterpret); + upr = upr->optimize(WANTvalue | WANTinterpret); uinteger_t i1 = lwr->toUInteger(); uinteger_t i2 = upr->toUInteger(); @@ -9033,7 +9041,26 @@ Expression *AssignExp::semantic(Scope *sc) if (op == TOKassign) { Expression *e = op_overload(sc); - if (e) + if (e && e1->op == TOKindex && + ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray) + { + // Deal with AAs (Bugzilla 2451) + // Rewrite as: + // e1 = (typeof(e2) tmp = void, tmp = e2, tmp); + Identifier *id = Lexer::uniqueId("__aatmp"); + VarDeclaration *v = new VarDeclaration(loc, e2->type, + id, new VoidInitializer(NULL)); + v->storage_class |= STCctfe; + + Expression *de = new DeclarationExp(loc, v); + VarExp *ve = new VarExp(loc, v); + + AssignExp *ae = new AssignExp(loc, ve, e2); + e = ae->op_overload(sc); + e2 = new CommaExp(loc, new CommaExp(loc, de, e), ve); + e2 = e2->semantic(sc); + } + else if (e) return e; } else if (op == TOKconstruct && !refinit) @@ -9355,6 +9382,7 @@ CatAssignExp::CatAssignExp(Loc loc, Expression *e1, Expression *e2) Expression *CatAssignExp::semantic(Scope *sc) { Expression *e; + //printf("CatAssignExp::semantic() %s\n", toChars()); e = op_overload(sc); if (e) return e; @@ -10747,6 +10775,14 @@ RemoveExp::RemoveExp(Loc loc, Expression *e1, Expression *e2) type = Type::tvoid; } +void RemoveExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ + expToCBuffer(buf, hgs, e1, PREC_primary); + buf->writestring(".remove("); + expToCBuffer(buf, hgs, e2, PREC_assign); + buf->writestring(")"); +} + /************************************************************/ CmpExp::CmpExp(enum TOK op, Loc loc, Expression *e1, Expression *e2) diff --git a/dmd2/expression.h b/dmd2/expression.h index 6e8ea740..2bbbc38e 100644 --- a/dmd2/expression.h +++ b/dmd2/expression.h @@ -1912,6 +1912,7 @@ struct InExp : BinExp struct RemoveExp : BinExp { RemoveExp(Loc loc, Expression *e1, Expression *e2); + void toCBuffer(OutBuffer *buf, HdrGenState *hgs); #if IN_DMD elem *toElem(IRState *irs); #endif diff --git a/dmd2/func.c b/dmd2/func.c index f6020c1f..9f581356 100644 --- a/dmd2/func.c +++ b/dmd2/func.c @@ -55,6 +55,7 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageCla #if IN_GCC v_argptr = NULL; #endif + v_argsave = NULL; parameters = NULL; labtab = NULL; overnext = NULL; @@ -805,6 +806,7 @@ void FuncDeclaration::semantic3(Scope *sc) { TypeFunction *f; VarDeclaration *argptr = NULL; VarDeclaration *_arguments = NULL; + int nerrors = global.errors; if (!parent) { @@ -903,8 +905,8 @@ void FuncDeclaration::semantic3(Scope *sc) #if STRUCTTHISREF thandle = thandle->addMod(type->mod); thandle = thandle->addStorageClass(storage_class); - if (isPure()) - thandle = thandle->addMod(MODconst); + //if (isPure()) + //thandle = thandle->addMod(MODconst); #else if (storage_class & STCconst || type->isConst()) { @@ -1005,6 +1007,20 @@ void FuncDeclaration::semantic3(Scope *sc) } #endif } + if (global.params.is64bit && f->varargs && f->linkage == LINKc) + { // Declare save area for varargs registers + Type *t = new TypeIdentifier(loc, Id::va_argsave_t); + t = t->semantic(loc, sc); + if (t == Type::terror) + error("must import std.c.stdarg to use variadic functions"); + else + { + v_argsave = new VarDeclaration(loc, t, Id::va_argsave, NULL); + v_argsave->semantic(sc2); + sc2->insert(v_argsave); + v_argsave->parent = this; + } + } #if IN_LLVM // LDC make sure argument type is semanticed. @@ -1072,8 +1088,8 @@ void FuncDeclaration::semantic3(Scope *sc) arg->ident = id = Identifier::generateId("_param_", i); } Type *vtype = arg->type; - if (isPure()) - vtype = vtype->addMod(MODconst); + //if (isPure()) + //vtype = vtype->addMod(MODconst); VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL); //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars()); v->storage_class |= STCparameter; @@ -1716,7 +1732,11 @@ void FuncDeclaration::semantic3(Scope *sc) sc2->callSuper = 0; sc2->pop(); } - semanticRun = PASSsemantic3done; + + if (global.gag && global.errors != nerrors) + semanticRun = PASSsemanticdone; // Ensure errors get reported again + else + semanticRun = PASSsemantic3done; } void FuncDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) @@ -1798,6 +1818,16 @@ Statement *FuncDeclaration::mergeFrequire(Statement *sf) for (int i = 0; i < foverrides.dim; i++) { FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i]; + + /* The semantic pass on the contracts of the overridden functions must + * be completed before code generation occurs (bug 3602). + */ + if (fdv->fdrequire && fdv->fdrequire->semanticRun != PASSsemantic3done) + { + assert(fdv->scope); + fdv->semantic3(fdv->scope); + } + sf = fdv->mergeFrequire(sf); if (fdv->fdrequire) { @@ -2674,11 +2704,24 @@ int FuncDeclaration::isOverloadable() return 1; // functions can be overloaded } -int FuncDeclaration::isPure() +enum PURE FuncDeclaration::isPure() { //printf("FuncDeclaration::isPure() '%s'\n", toChars()); assert(type->ty == Tfunction); - return ((TypeFunction *)this->type)->ispure; + TypeFunction *tf = (TypeFunction *)type; + enum PURE purity = tf->purity; + if (purity == PUREfwdref) + tf->purityLevel(); + if (purity > PUREweak && needThis()) + { // The attribute of the 'this' reference affects purity strength + if (type->mod & (MODimmutable | MODwild)) + ; + else if (type->mod & MODconst && purity >= PUREconst) + purity = PUREconst; + else + purity = PUREweak; + } + return purity; } int FuncDeclaration::isSafe() diff --git a/dmd2/idgen.c b/dmd2/idgen.c index 1691da58..bbd3213e 100644 --- a/dmd2/idgen.c +++ b/dmd2/idgen.c @@ -1,9 +1,10 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2008 by Digital Mars +// Copyright (c) 1999-2010 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com +// http://www.dsource.org/projects/dmd/browser/trunk/src/idgen.c // License for redistribution is by either the Artistic License // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. @@ -295,6 +296,10 @@ Msgtable msgtable[] = { "DllMain" }, { "tls_get_addr", "___tls_get_addr" }, + // varargs implementation + { "va_argsave_t", "__va_argsave_t" }, + { "va_argsave", "__va_argsave" }, + // Builtin functions { "std" }, { "math" }, diff --git a/dmd2/interpret.c b/dmd2/interpret.c index 41ae5335..250be4a8 100644 --- a/dmd2/interpret.c +++ b/dmd2/interpret.c @@ -564,13 +564,13 @@ Expression *ReturnStatement::interpret(InterState *istate) } #endif -#if LOG Expression *e = exp->interpret(istate); - printf("e = %p\n", e); + if (e == EXP_CANT_INTERPRET) + return e; + // Convert lvalues into rvalues (See Bugzilla 4825 for rationale) + if (e->op == TOKvar) + e = e->interpret(istate); return e; -#else - return exp->interpret(istate); -#endif } Expression *BreakStatement::interpret(InterState *istate) @@ -2710,21 +2710,32 @@ Expression *CallExp::interpret(InterState *istate) Expression * pe = ((PtrExp*)ecall)->e1; if (pe->op == TOKvar) { VarDeclaration *vd = ((VarExp *)((PtrExp*)ecall)->e1)->var->isVarDeclaration(); - if (vd && vd->value && vd->value->op==TOKsymoff) + if (vd && vd->value && vd->value->op == TOKsymoff) fd = ((SymOffExp *)vd->value)->var->isFuncDeclaration(); else { ecall = vd->value->interpret(istate); - if (ecall->op==TOKsymoff) + if (ecall->op == TOKsymoff) fd = ((SymOffExp *)ecall)->var->isFuncDeclaration(); } } else ecall = ((PtrExp*)ecall)->e1->interpret(istate); + } + if (ecall == EXP_CANT_INTERPRET) + return ecall; + if (ecall->op == TOKindex) - ecall = e1->interpret(istate); + { ecall = e1->interpret(istate); + if (ecall == EXP_CANT_INTERPRET) + return ecall; + } + if (ecall->op == TOKdotvar && !((DotVarExp*)ecall)->var->isFuncDeclaration()) - ecall = e1->interpret(istate); + { ecall = e1->interpret(istate); + if (ecall == EXP_CANT_INTERPRET) + return ecall; + } if (ecall->op == TOKdotvar) { // Calling a member function diff --git a/dmd2/mars.c b/dmd2/mars.c index 2333c7fb..a9908b5e 100644 --- a/dmd2/mars.c +++ b/dmd2/mars.c @@ -4,6 +4,7 @@ // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com +// http://www.dsource.org/projects/dmd/browser/trunk/src/mars.c // License for redistribution is by either the Artistic License // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. @@ -99,7 +100,7 @@ Global::Global() "\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates."; #endif ; - version = "v2.049"; + version = "v2.050"; #if IN_LLVM ldc_version = "LDC trunk"; llvm_version = "LLVM 2.8"; @@ -237,6 +238,8 @@ void halt() #endif } + +extern signed char tyalignsize[]; /*********************************** * Parse and append contents of environment variable envvar * to argc and argv[]. diff --git a/dmd2/mtype.c b/dmd2/mtype.c index 685477f9..0e2d4afe 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -4,6 +4,7 @@ // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com +// http://www.dsource.org/projects/dmd/browser/trunk/src/mtype.c // License for redistribution is by either the Artistic License // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. @@ -3480,7 +3481,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) return this; } dinteger_t d1 = dim->toInteger(); - dim = dim->castTo(sc, tsize_t); + dim = dim->implicitCastTo(sc, tsize_t); dim = dim->optimize(WANTvalue); dinteger_t d2 = dim->toInteger(); @@ -4585,7 +4586,7 @@ TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, e this->linkage = linkage; this->inuse = 0; this->isnothrow = false; - this->ispure = false; + this->purity = PUREimpure; this->isproperty = false; this->isref = false; this->fargs = NULL; @@ -4594,7 +4595,7 @@ TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, e this->funcdecl = NULL; #endif if (stc & STCpure) - this->ispure = true; + this->purity = PUREfwdref; if (stc & STCnothrow) this->isnothrow = true; if (stc & STCproperty) @@ -4616,7 +4617,7 @@ Type *TypeFunction::syntaxCopy() TypeFunction *t = new TypeFunction(params, treturn, varargs, linkage); t->mod = mod; t->isnothrow = isnothrow; - t->ispure = ispure; + t->purity = purity; t->isproperty = isproperty; t->isref = isref; t->trust = trust; @@ -4750,7 +4751,7 @@ Lcovariant: /* Can convert pure to impure, and nothrow to throw */ - if (!t1->ispure && t2->ispure) + if (!t1->purity && t2->purity) goto Lnotcovariant; if (!t1->isnothrow && t2->isnothrow) @@ -4802,9 +4803,9 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) assert(0); } buf->writeByte(mc); - if (ispure || isnothrow || isproperty || isref || trust) + if (purity || isnothrow || isproperty || isref || trust) { - if (ispure) + if (purity) buf->writestring("Na"); if (isnothrow) buf->writestring("Nb"); @@ -4876,7 +4877,7 @@ void TypeFunction::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs buf->writeByte(' '); } - if (ispure) + if (purity) buf->writestring("pure "); if (isnothrow) buf->writestring("nothrow "); @@ -4976,7 +4977,7 @@ void TypeFunction::attributesToCBuffer(OutBuffer *buf, int mod) { modToBuffer(buf); } - if (ispure) + if (purity) buf->writestring(" pure"); if (isnothrow) buf->writestring(" nothrow"); @@ -5028,7 +5029,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc) } if (sc->stc & STCpure) - tf->ispure = TRUE; + tf->purity = PUREfwdref; if (sc->stc & STCnothrow) tf->isnothrow = TRUE; if (sc->stc & STCref) @@ -5205,6 +5206,84 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc) return tf; } + +/******************************************** + * Do this lazily, as the parameter types might be forward referenced. + */ +void TypeFunction::purityLevel() +{ + TypeFunction *tf = this; + if (tf->purity == PUREfwdref) + { /* Evaluate what kind of purity based on the modifiers for the parameters + */ + tf->purity = PUREstrong; // assume strong until something weakens it + if (tf->parameters) + { + size_t dim = Parameter::dim(tf->parameters); + for (size_t i = 0; i < dim; i++) + { Parameter *fparam = Parameter::getNth(tf->parameters, i); + if (fparam->storageClass & STClazy) + { + /* We could possibly allow this by doing further analysis on the + * lazy parameter to see if it's pure. + */ + error(0, "cannot have lazy parameters to a pure function"); + } + if (fparam->storageClass & STCout) + { + tf->purity = PUREweak; + break; + } + if (!fparam->type) + continue; + if (fparam->storageClass & STCref) + { + if (!(fparam->type->mod & (MODconst | MODimmutable | MODwild))) + { tf->purity = PUREweak; + break; + } + if (fparam->type->mod & MODconst) + { tf->purity = PUREconst; + continue; + } + } + Type *t = fparam->type->toBasetype(); + if (!t->hasPointers()) + continue; + if (t->mod & (MODimmutable | MODwild)) + continue; + /* The rest of this is too strict; fix later. + * For example, the only pointer members of a struct may be immutable, + * which would maintain strong purity. + */ + if (t->mod & MODconst) + { tf->purity = PUREconst; + continue; + } + Type *tn = t->nextOf(); + if (tn) + { tn = tn->toBasetype(); + if (tn->ty == Tpointer || tn->ty == Tarray) + { /* Accept immutable(T)* and immutable(T)[] as being strongly pure + */ + if (tn->mod & (MODimmutable | MODwild)) + continue; + if (tn->mod & MODconst) + { tf->purity = PUREconst; + continue; + } + } + } + /* Should catch delegates and function pointers, and fold in their purity + */ + tf->purity = PUREweak; // err on the side of too strict + break; + } + } + } +} + + /******************************** * 'args' are being matched to function 'this' * Determine match level. @@ -5425,7 +5504,7 @@ bool TypeFunction::parameterEscapes(Parameter *p) if (p->storageClass & (STCscope | STClazy)) return FALSE; - if (ispure) + if (purity) { /* With pure functions, we need only be concerned if p escapes * via any return statement. */ @@ -6039,7 +6118,7 @@ Type *TypeInstance::semantic(Loc loc, Scope *sc) printf("2: "); #endif error(loc, "%s is used as a type", toChars()); - t = tvoid; + t = terror; } return t; } @@ -7979,11 +8058,11 @@ Type *TypeSlice::semantic(Loc loc, Scope *sc) TypeTuple *tt = (TypeTuple *)tbn; lwr = semanticLength(sc, tbn, lwr); - lwr = lwr->optimize(WANTvalue); + lwr = lwr->optimize(WANTvalue | WANTinterpret); uinteger_t i1 = lwr->toUInteger(); upr = semanticLength(sc, tbn, upr); - upr = upr->optimize(WANTvalue); + upr = upr->optimize(WANTvalue | WANTinterpret); uinteger_t i2 = upr->toUInteger(); if (!(i1 <= i2 && i2 <= tt->arguments->dim)) @@ -8023,11 +8102,11 @@ void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol sc = sc->push(sym); lwr = lwr->semantic(sc); - lwr = lwr->optimize(WANTvalue); + lwr = lwr->optimize(WANTvalue | WANTinterpret); uinteger_t i1 = lwr->toUInteger(); upr = upr->semantic(sc); - upr = upr->optimize(WANTvalue); + upr = upr->optimize(WANTvalue | WANTinterpret); uinteger_t i2 = upr->toUInteger(); sc = sc->pop(); diff --git a/dmd2/mtype.h b/dmd2/mtype.h index bb2e0e19..d1d337fd 100644 --- a/dmd2/mtype.h +++ b/dmd2/mtype.h @@ -589,6 +589,15 @@ enum TRUST TRUSTsafe = 3, // @safe }; +enum PURE +{ + PUREimpure = 0, // not pure at all + PUREweak = 1, // no mutable globals are read or written + PUREconst = 2, // parameters are values or const + PUREstrong = 3, // parameters are values or immutable + PUREfwdref = 4, // it's pure, but not known which level yet +}; + struct TypeFunction : TypeNext { // .next is the return type @@ -597,11 +606,11 @@ struct TypeFunction : TypeNext int varargs; // 1: T t, ...) style for variable number of arguments // 2: T t ...) style for variable number of arguments bool isnothrow; // true: nothrow - bool ispure; // true: pure bool isproperty; // can be called without parentheses bool isref; // true: returns a reference enum LINK linkage; // calling convention enum TRUST trust; // level of trust + enum PURE purity; // PURExxxx Expressions *fargs; // function arguments int inuse; @@ -609,6 +618,7 @@ struct TypeFunction : TypeNext TypeFunction(Parameters *parameters, Type *treturn, int varargs, enum LINK linkage, StorageClass stc = 0); Type *syntaxCopy(); Type *semantic(Loc loc, Scope *sc); + void purityLevel(); void toDecoBuffer(OutBuffer *buf, int flag, bool mangle); void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); diff --git a/dmd2/opover.c b/dmd2/opover.c index 338019c0..68dded02 100644 --- a/dmd2/opover.c +++ b/dmd2/opover.c @@ -251,7 +251,7 @@ Expression *UnaExp::op_overload(Scope *sc) ((ArrayExp *)e1)->e1 = new DotIdExp(loc, ae->e1, ad->aliasthis->ident); Expression *e = copy(); ((UnaExp *)e)->e1 = e1; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } } @@ -294,7 +294,7 @@ Expression *UnaExp::op_overload(Scope *sc) ((SliceExp *)e1)->e1 = new DotIdExp(loc, se->e1, ad->aliasthis->ident); Expression *e = copy(); ((UnaExp *)e)->e1 = e1; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } } @@ -356,7 +356,7 @@ Expression *UnaExp::op_overload(Scope *sc) Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident); Expression *e = copy(); ((UnaExp *)e)->e1 = e1; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } #endif @@ -391,7 +391,7 @@ Expression *ArrayExp::op_overload(Scope *sc) Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident); Expression *e = copy(); ((UnaExp *)e)->e1 = e1; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } } @@ -438,7 +438,7 @@ Expression *CastExp::op_overload(Scope *sc) Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident); Expression *e = copy(); ((UnaExp *)e)->e1 = e1; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } } @@ -683,7 +683,8 @@ L1: #if DMDV2 // Try alias this on first operand - if (ad1 && ad1->aliasthis) + if (ad1 && ad1->aliasthis && + !(op == TOKassign && ad2 && ad1 == ad2)) // See Bugzilla 2943 { /* Rewrite (e1 op e2) as: * (e1.aliasthis op e2) @@ -691,12 +692,16 @@ L1: Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident); Expression *e = copy(); ((BinExp *)e)->e1 = e1; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } // Try alias this on second operand - if (ad2 && ad2->aliasthis) + if (ad2 && ad2->aliasthis && + /* Bugzilla 2943: make sure that when we're copying the struct, we don't + * just copy the alias this member + */ + !(op == TOKassign && ad1 && ad1 == ad2)) { /* Rewrite (e1 op e2) as: * (e1 op e2.aliasthis) @@ -704,7 +709,7 @@ L1: Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident); Expression *e = copy(); ((BinExp *)e)->e2 = e2; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } #endif @@ -860,7 +865,7 @@ Expression *BinExp::compare_overload(Scope *sc, Identifier *id) Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident); Expression *e = copy(); ((BinExp *)e)->e1 = e1; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } @@ -873,7 +878,7 @@ Expression *BinExp::compare_overload(Scope *sc, Identifier *id) Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident); Expression *e = copy(); ((BinExp *)e)->e2 = e2; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } @@ -954,7 +959,7 @@ Expression *BinAssignExp::op_overload(Scope *sc) ((ArrayExp *)e1)->e1 = new DotIdExp(loc, ae->e1, ad->aliasthis->ident); Expression *e = copy(); ((UnaExp *)e)->e1 = e1; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } } @@ -998,7 +1003,7 @@ Expression *BinAssignExp::op_overload(Scope *sc) ((SliceExp *)e1)->e1 = new DotIdExp(loc, se->e1, ad->aliasthis->ident); Expression *e = copy(); ((UnaExp *)e)->e1 = e1; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } } @@ -1099,7 +1104,7 @@ L1: Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident); Expression *e = copy(); ((BinExp *)e)->e1 = e1; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } @@ -1113,7 +1118,7 @@ L1: Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident); Expression *e = copy(); ((BinExp *)e)->e2 = e2; - e = e->semantic(sc); + e = e->trySemantic(sc); return e; } #endif diff --git a/dmd2/optimize.c b/dmd2/optimize.c index 35abcd02..911992da 100644 --- a/dmd2/optimize.c +++ b/dmd2/optimize.c @@ -138,7 +138,15 @@ Expression *fromConstInitializer(int result, Expression *e1) int fwdref = (v && !v->originalType && v->scope); e = expandVar(result, v); if (e) - { if (e->type != e1->type && e1->type && e1->type->ty != Tident) + { + // If it is a comma expression involving a declaration, we mustn't + // perform a copy -- we'd get two declarations of the same variable. + // See bugzilla 4465. + if (e->op == TOKcomma && ((CommaExp *)e)->e1->op == TOKdeclaration) + e = e1; + else + + if (e->type != e1->type && e1->type && e1->type->ty != Tident) { // Type 'paint' operation e = e->copy(); e->type = e1->type; diff --git a/dmd2/parse.c b/dmd2/parse.c index 4f11e221..712dc95f 100644 --- a/dmd2/parse.c +++ b/dmd2/parse.c @@ -2413,12 +2413,6 @@ Type *Parser::parseBasicType2(Type *t) t = new TypeDArray(t); // [] nextToken(); } - else if (token.value == TOKnew && peekNext() == TOKrbracket) - { - t = new TypeNewArray(t); // [new] - nextToken(); - nextToken(); - } else if (isDeclaration(&token, 0, TOKrbracket, NULL)) { // It's an associative array declaration @@ -2498,14 +2492,39 @@ Type *Parser::parseDeclarator(Type *t, Identifier **pident, TemplateParameters * break; case TOKlparen: - /* Parse things with parentheses around the identifier, like: - * int (*ident[3])[] - * although the D style would be: - * int[]*[3] ident + if (peekNext() == TOKmul || // like: T (*fp)(); + peekNext() == TOKlparen // like: T ((*fp))(); + /* || peekNext() == TOKlbracket*/) // like: T ([] a) + { + /* Parse things with parentheses around the identifier, like: + * int (*ident[3])[] + * although the D style would be: + * int[]*[3] ident + */ + if (!global.params.useDeprecated) + { + error("C-style function pointer and pointer to array syntax is deprecated. Use 'function' to declare function pointers"); + } + nextToken(); + ts = parseDeclarator(t, pident); + check(TOKrparen); + break; + } + ts = t; + { + Token *peekt = &token; + /* Completely disallow C-style things like: + * T (a); + * Improve error messages for the common bug of a missing return type + * by looking to see if (a) looks like a parameter list. */ - nextToken(); - ts = parseDeclarator(t, pident); - check(TOKrparen); + if (isParameters(&peekt)) { + error("function declaration without return type. " + "(Note that constructors are always named 'this')"); + } + else + error("unexpected ( in declarator"); + } break; default: @@ -2533,12 +2552,6 @@ Type *Parser::parseDeclarator(Type *t, Identifier **pident, TemplateParameters * ta = new TypeDArray(t); // [] nextToken(); } - else if (token.value == TOKnew && peekNext() == TOKrbracket) - { - t = new TypeNewArray(t); // [new] - nextToken(); - nextToken(); - } else if (isDeclaration(&token, 0, TOKrbracket, NULL)) { // It's an associative array @@ -4457,11 +4470,6 @@ int Parser::isDeclarator(Token **pt, int *haveId, enum TOK endtok) { t = peek(t); } - else if (t->value == TOKnew && peek(t)->value == TOKrbracket) - { - t = peek(t); - t = peek(t); - } else if (isDeclaration(t, 0, TOKrbracket, &t)) { // It's an associative array declaration t = peek(t); @@ -6273,37 +6281,53 @@ void initPrecedence() precedence[TOKsuper] = PREC_primary; precedence[TOKint64] = PREC_primary; precedence[TOKfloat64] = PREC_primary; + precedence[TOKcomplex80] = PREC_primary; precedence[TOKnull] = PREC_primary; precedence[TOKstring] = PREC_primary; precedence[TOKarrayliteral] = PREC_primary; + precedence[TOKassocarrayliteral] = PREC_primary; +#if DMDV2 + precedence[TOKfile] = PREC_primary; + precedence[TOKline] = PREC_primary; +#endif precedence[TOKtypeid] = PREC_primary; precedence[TOKis] = PREC_primary; precedence[TOKassert] = PREC_primary; + precedence[TOKhalt] = PREC_primary; + precedence[TOKtemplate] = PREC_primary; + precedence[TOKdsymbol] = PREC_primary; precedence[TOKfunction] = PREC_primary; precedence[TOKvar] = PREC_primary; precedence[TOKsymoff] = PREC_primary; precedence[TOKstructliteral] = PREC_primary; precedence[TOKarraylength] = PREC_primary; + precedence[TOKremove] = PREC_primary; precedence[TOKtuple] = PREC_primary; #if DMDV2 precedence[TOKtraits] = PREC_primary; precedence[TOKdefault] = PREC_primary; + precedence[TOKoverloadset] = PREC_primary; #endif // post precedence[TOKdotti] = PREC_primary; precedence[TOKdot] = PREC_primary; precedence[TOKdottd] = PREC_primary; + precedence[TOKdotexp] = PREC_primary; + precedence[TOKdottype] = PREC_primary; // precedence[TOKarrow] = PREC_primary; precedence[TOKplusplus] = PREC_primary; precedence[TOKminusminus] = PREC_primary; +#if DMDV2 precedence[TOKpreplusplus] = PREC_primary; precedence[TOKpreminusminus] = PREC_primary; +#endif precedence[TOKcall] = PREC_primary; precedence[TOKslice] = PREC_primary; precedence[TOKarray] = PREC_primary; precedence[TOKindex] = PREC_primary; + precedence[TOKdelegate] = PREC_unary; precedence[TOKaddress] = PREC_unary; precedence[TOKstar] = PREC_unary; precedence[TOKneg] = PREC_unary; @@ -6313,14 +6337,16 @@ void initPrecedence() precedence[TOKtilde] = PREC_unary; precedence[TOKdelete] = PREC_unary; precedence[TOKnew] = PREC_unary; + precedence[TOKnewanonclass] = PREC_unary; precedence[TOKcast] = PREC_unary; +#if DMDV2 precedence[TOKpow] = PREC_pow; +#endif precedence[TOKmul] = PREC_mul; precedence[TOKdiv] = PREC_mul; precedence[TOKmod] = PREC_mul; - precedence[TOKpow] = PREC_mul; precedence[TOKadd] = PREC_add; precedence[TOKmin] = PREC_add; @@ -6380,7 +6406,9 @@ void initPrecedence() precedence[TOKmulass] = PREC_assign; precedence[TOKdivass] = PREC_assign; precedence[TOKmodass] = PREC_assign; +#if DMDV2 precedence[TOKpowass] = PREC_assign; +#endif precedence[TOKshlass] = PREC_assign; precedence[TOKshrass] = PREC_assign; precedence[TOKushrass] = PREC_assign; diff --git a/dmd2/statement.c b/dmd2/statement.c index 9c0ef3e3..f7db947b 100644 --- a/dmd2/statement.c +++ b/dmd2/statement.c @@ -4286,6 +4286,9 @@ int TryCatchStatement::blockExit() for (size_t i = 0; i < catches->dim; i++) { Catch *c = (Catch *)catches->data[i]; + if (c->type == Type::terror) + continue; + catchresult |= c->blockExit(); /* If we're catching Object, then there is no throwing @@ -4361,7 +4364,12 @@ void Catch::semantic(Scope *sc) type = new TypeIdentifier(0, Id::Object); type = type->semantic(loc, sc); if (!type->toBasetype()->isClassHandle()) - error(loc, "can only catch class objects, not '%s'", type->toChars()); + { + if (type != Type::terror) + { error(loc, "can only catch class objects, not '%s'", type->toChars()); + type = Type::terror; + } + } else if (ident) { var = new VarDeclaration(loc, type, ident, NULL); diff --git a/dmd2/staticassert.c b/dmd2/staticassert.c index e80e4603..fcbe913e 100644 --- a/dmd2/staticassert.c +++ b/dmd2/staticassert.c @@ -1,8 +1,9 @@ -// Copyright (c) 1999-2007 by Digital Mars +// Copyright (c) 1999-2010 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com +// http://www.dsource.org/projects/dmd/browser/trunk/src/staticassert.c // License for redistribution is by either the Artistic License // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. @@ -55,6 +56,8 @@ void StaticAssert::semantic2(Scope *sc) //printf("StaticAssert::semantic2() %s\n", toChars()); e = exp->semantic(sc); + if (e->op == TOKerror) + return; e = e->optimize(WANTvalue | WANTinterpret); if (e->isBool(FALSE)) { diff --git a/dmd2/struct.c b/dmd2/struct.c index 0e83d221..8d6b765b 100644 --- a/dmd2/struct.c +++ b/dmd2/struct.c @@ -226,11 +226,14 @@ void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v) if (!isUnionDeclaration()) sc->offset = ofs; #endif - if (sc->structalign < memalignsize) + if (global.params.is64bit && sc->structalign == 8 && memalignsize == 16) + /* Not sure how to handle this */ + ; + else if (sc->structalign < memalignsize) memalignsize = sc->structalign; if (alignsize < memalignsize) alignsize = memalignsize; - //printf("\talignsize = %d\n", alignsize); + //printf("\t%s: alignsize = %d\n", toChars(), alignsize); v->storage_class |= STCfield; //printf(" addField '%s' to '%s' at offset %d, size = %d\n", v->toChars(), toChars(), v->offset, memsize); diff --git a/dmd2/template.c b/dmd2/template.c index ebd9ad5d..2954b242 100644 --- a/dmd2/template.c +++ b/dmd2/template.c @@ -894,6 +894,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec ScopeDsymbol *paramsym = new ScopeDsymbol(); paramsym->parent = scope->parent; Scope *paramscope = scope->push(paramsym); + paramscope->stc = 0; TemplateTupleParameter *tp = isVariadic(); int tp_is_declared = 0; diff --git a/druntime.patch b/druntime.patch index 9e64e253..64a5affc 100644 --- a/druntime.patch +++ b/druntime.patch @@ -1,6 +1,6 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-orig/import/ldc/cstdarg.di druntime/import/ldc/cstdarg.di --- druntime-orig/import/ldc/cstdarg.di 1970-01-01 03:00:00.000000000 +0300 -+++ druntime/import/ldc/cstdarg.di 2010-11-05 13:57:24.315267000 +0300 ++++ druntime/import/ldc/cstdarg.di 2010-11-05 13:57:24.000000000 +0300 @@ -0,0 +1,29 @@ +/* + * vararg support for extern(C) functions @@ -417,7 +417,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. +} diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-orig/import/ldc/vararg.d druntime/import/ldc/vararg.d --- druntime-orig/import/ldc/vararg.d 1970-01-01 03:00:00.000000000 +0300 -+++ druntime/import/ldc/vararg.d 2010-11-05 13:57:12.991267001 +0300 ++++ druntime/import/ldc/vararg.d 2010-11-05 13:57:12.000000000 +0300 @@ -0,0 +1,43 @@ +/* + * This module holds the implementation of special vararg templates for D style var args. @@ -463,18 +463,9 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. + dst = src; +} diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-orig/import/object.di druntime/import/object.di ---- druntime-orig/import/object.di 2010-09-03 12:28:52.000000000 +0400 -+++ druntime/import/object.di 2010-11-04 17:49:07.000000000 +0300 -@@ -130,7 +130,7 @@ - Interface[] interfaces; - TypeInfo_Class base; - void* destructor; -- void(*classInvariant)(Object); -+ void function(Object) classInvariant; - uint m_flags; - // 1: // is IUnknown or is derived from IUnknown - // 2: // has no possible pointers into GC memory -@@ -140,7 +140,7 @@ +--- druntime-orig/import/object.di 2010-10-13 10:37:58.000000000 +0400 ++++ druntime/import/object.di 2010-11-07 19:11:32.000000000 +0300 +@@ -142,7 +142,7 @@ // 32: // has typeinfo member void* deallocator; OffsetTypeInfo[] m_offTi; @@ -483,7 +474,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. const(MemberInfo[]) function(string) xgetMembers; static TypeInfo_Class find(in char[] classname); -@@ -179,7 +179,7 @@ +@@ -189,7 +189,7 @@ class TypeInfo_Const : TypeInfo { @@ -492,7 +483,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. } class TypeInfo_Invariant : TypeInfo_Const -@@ -288,7 +288,6 @@ +@@ -298,7 +298,6 @@ interface TraceInfo { int opApply(scope int delegate(ref char[])); @@ -501,8 +492,8 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. string msg; diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-orig/src/core/atomic.d druntime/src/core/atomic.d ---- druntime-orig/src/core/atomic.d 2010-09-03 12:28:52.000000000 +0400 -+++ druntime/src/core/atomic.d 2010-11-04 17:49:07.000000000 +0300 +--- druntime-orig/src/core/atomic.d 2010-10-11 00:37:54.000000000 +0400 ++++ druntime/src/core/atomic.d 2010-11-07 19:11:32.000000000 +0300 @@ -89,6 +89,117 @@ return false; } @@ -677,8 +668,8 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. { // use the unoptimized version diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-orig/src/gc/gcx.d druntime/src/gc/gcx.d ---- druntime-orig/src/gc/gcx.d 2010-08-27 01:23:26.000000000 +0400 -+++ druntime/src/gc/gcx.d 2010-11-06 18:16:41.638720001 +0300 +--- druntime-orig/src/gc/gcx.d 2010-10-03 10:52:12.000000000 +0400 ++++ druntime/src/gc/gcx.d 2010-11-07 19:11:32.000000000 +0300 @@ -1464,7 +1464,8 @@ @@ -906,9 +897,9 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. thread_suspendAll(); diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-orig/src/object_.d druntime/src/object_.d ---- druntime-orig/src/object_.d 2010-09-03 12:28:52.000000000 +0400 -+++ druntime/src/object_.d 2010-11-06 19:28:37.000000000 +0300 -@@ -1663,7 +1663,6 @@ +--- druntime-orig/src/object_.d 2010-10-13 10:37:58.000000000 +0400 ++++ druntime/src/object_.d 2010-11-07 19:11:32.000000000 +0300 +@@ -1754,7 +1754,6 @@ { int len = 0; ModuleReference *mr; @@ -916,7 +907,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. for (mr = _Dmodule_ref; mr; mr = mr.next) len++; _moduleinfo_array = new ModuleInfo*[len]; -@@ -2025,7 +2024,6 @@ +@@ -2116,7 +2115,6 @@ _d_monitor_create(h); m = getMonitor(h); } @@ -924,7 +915,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. IMonitor i = m.impl; if (i is null) -@@ -2124,7 +2122,7 @@ +@@ -2215,7 +2213,7 @@ size_t _aaLen(void* p); void* _aaGet(void** pp, TypeInfo keyti, size_t valuesize, ...); void* _aaGetRvalue(void* p, TypeInfo keyti, size_t valuesize, ...); @@ -933,7 +924,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. void _aaDel(void* p, TypeInfo keyti, ...); void[] _aaValues(void* p, size_t keysize, size_t valuesize); void[] _aaKeys(void* p, size_t keysize, size_t valuesize); -@@ -2169,7 +2167,7 @@ +@@ -2260,7 +2258,7 @@ return *cast(Key[]*) &a; } @@ -944,7 +935,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. } diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-orig/src/rt/aaA.d druntime/src/rt/aaA.d --- druntime-orig/src/rt/aaA.d 2010-08-05 05:39:06.000000000 +0400 -+++ druntime/src/rt/aaA.d 2010-11-05 11:43:19.831267002 +0300 ++++ druntime/src/rt/aaA.d 2010-11-05 11:43:19.000000000 +0300 @@ -204,7 +204,7 @@ * Add entry for key if it is not already there. */ @@ -1776,8 +1767,8 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. + _Unwind_Resume(&exception_struct.unwind_info); +} diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-orig/src/rt/lifetime.d druntime/src/rt/lifetime.d ---- druntime-orig/src/rt/lifetime.d 2010-08-05 05:39:06.000000000 +0400 -+++ druntime/src/rt/lifetime.d 2010-11-05 11:43:02.207267001 +0300 +--- druntime-orig/src/rt/lifetime.d 2010-10-12 07:07:36.000000000 +0400 ++++ druntime/src/rt/lifetime.d 2010-11-07 19:12:13.000000000 +0300 @@ -92,6 +92,18 @@ return gc_malloc(sz); } @@ -1797,52 +1788,25 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. /** * -@@ -670,7 +682,7 @@ - * ti is the type of the resulting array, or pointer to element. - * (For when the array is initialized to 0) - */ --extern (C) ulong _d_newarrayT(TypeInfo ti, size_t length) -+extern (C) void[] _d_newarrayT(TypeInfo ti, size_t length) - { - ulong result; - auto size = ti.next.tsize(); // array element size @@ -702,7 +714,7 @@ __setArrayAllocLength(info, size, isshared); - result = cast(ulong)length + (cast(ulong)cast(size_t)arrstart << 32); + result = arrstart[0..length]; } - return result; + return *cast(void[]*)&result; Loverflow: onOutOfMemoryError(); -@@ -711,7 +723,7 @@ - /** - * For when the array has a non-zero initializer. - */ --extern (C) ulong _d_newarrayiT(TypeInfo ti, size_t length) -+extern (C) void[] _d_newarrayiT(TypeInfo ti, size_t length) - { - ulong result; - auto size = ti.next.tsize(); // array element size @@ -764,7 +776,7 @@ __setArrayAllocLength(info, size, isshared); - result = cast(ulong)length + (cast(ulong)cast(uint)arrstart << 32); + result = arrstart[0..length]; } - return result; + return *cast(void[]*)&result; Loverflow: onOutOfMemoryError(); -@@ -773,7 +785,7 @@ - /** - * - */ --extern (C) ulong _d_newarraymT(TypeInfo ti, int ndims, ...) -+extern (C) void[] _d_newarraymT(TypeInfo ti, int ndims, ...) - { - ulong result; - -@@ -823,14 +835,14 @@ +@@ -823,7 +835,7 @@ } va_end(q); } @@ -1851,14 +1815,6 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. } - /** - * - */ --extern (C) ulong _d_newarraymiT(TypeInfo ti, int ndims, ...) -+extern (C) void[] _d_newarraymiT(TypeInfo ti, int ndims, ...) - { - ulong result; - @@ -881,7 +893,7 @@ } va_end(q); @@ -1953,8 +1909,8 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-orig/src/rt/memory.d druntime/src/rt/memory.d ---- druntime-orig/src/rt/memory.d 2010-08-05 09:55:22.000000000 +0400 -+++ druntime/src/rt/memory.d 2010-11-06 19:35:02.518720000 +0300 +--- druntime-orig/src/rt/memory.d 2010-10-11 00:37:52.000000000 +0400 ++++ druntime/src/rt/memory.d 2010-11-07 19:11:32.000000000 +0300 @@ -12,6 +12,8 @@ */ module rt.memory; @@ -1964,7 +1920,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. private { -@@ -213,3 +215,616 @@ +@@ -230,3 +232,616 @@ static assert( false, "Operating system not supported." ); } } @@ -2581,7 +2537,6 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. +{ + static assert( false, "Compiler not supported." ); +} -\ No newline at end of file diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-orig/src/rt/qsort.d druntime/src/rt/qsort.d --- druntime-orig/src/rt/qsort.d 2010-08-05 05:39:06.000000000 +0400 +++ druntime/src/rt/qsort.d 2010-11-04 17:49:07.000000000 +0300 diff --git a/gen/toir.cpp b/gen/toir.cpp index 78d4bbf4..3b8f5473 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2786,15 +2786,20 @@ DValue* TupleExp::toElem(IRState *p) for (size_t i = 0; i < exps->dim; i++) { Expression *el = (Expression *)exps->data[i]; - DValue* ep = el->toElem(p); - types[i] = ep->getRVal()->getType(); + types[i] = DtoTypeNotVoid(el->type); } LLValue *val = DtoRawAlloca(LLStructType::get(gIR->context(), types),0, "tuple"); for (size_t i = 0; i < exps->dim; i++) { Expression *el = (Expression *)exps->data[i]; DValue* ep = el->toElem(p); - DtoStore(ep->getRVal(), DtoGEPi(val,0,i)); + LLValue *gep = DtoGEPi(val,0,i); + if (el->type->ty == Tstruct) + DtoStore(DtoLoad(ep->getRVal()), gep); + else if (el->type->ty != Tvoid) + DtoStore(ep->getRVal(), gep); + else + DtoStore(LLConstantInt::get(LLType::getInt8Ty(gIR->context()), 0, false), gep); } return new DImValue(type, val); } diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 7a4b967c..e10f66d1 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -117,6 +117,10 @@ const LLType* DtoType(Type* t) // aggregates case Tstruct: { TypeStruct* ts = (TypeStruct*)t; +#if 1 + if (t != ts->sym->type) // TODO: interesting... why does it happen? + ts->sym->type->irtype = NULL; // set irtype to NULL, so IrTypeStruct constructor would not assert... +#endif t->irtype = new IrTypeStruct(ts->sym); return t->irtype->buildType(); } diff --git a/gen/typinf.cpp b/gen/typinf.cpp index 1ff705a6..977d3116 100644 --- a/gen/typinf.cpp +++ b/gen/typinf.cpp @@ -661,7 +661,7 @@ void TypeInfoStructDeclaration::llvmDefine() ClassDeclaration* tscd = Type::typeinfostruct; - assert(tscd->fields.dim == 10); + assert(tscd->fields.dim == 11); // const(MemberInfo[]) function(in char[]) xgetMembers; VarDeclaration* xgetMembers = (VarDeclaration*)tscd->fields.data[7]; @@ -674,6 +674,9 @@ void TypeInfoStructDeclaration::llvmDefine() //void function(void*) xpostblit; VarDeclaration* xpostblit = (VarDeclaration*)tscd->fields.data[9]; b.push_null(xpostblit->type); + + //uint m_align; + b.push_uint(0); #endif // finish diff --git a/ir/irstruct.cpp b/ir/irstruct.cpp index 4a627a9b..118bdca5 100644 --- a/ir/irstruct.cpp +++ b/ir/irstruct.cpp @@ -149,7 +149,8 @@ LLConstant * IrStruct::createStructDefaultInitializer() assert(type->ty == Tstruct && "cannot build struct default initializer for non struct type"); - IrTypeStruct* ts = type->irtype->isStruct(); + DtoType(type); + IrTypeStruct* ts = stripModifiers(type)->irtype->isStruct(); assert(ts); // start at offset zero diff --git a/phobos.patch b/phobos.patch index 751759e3..4a33e826 100644 --- a/phobos.patch +++ b/phobos.patch @@ -1,7 +1,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- phobos-orig/std/concurrency.d phobos/std/concurrency.d ---- phobos-orig/std/concurrency.d 2010-09-17 00:27:48.000000000 +0400 -+++ phobos/std/concurrency.d 2010-11-02 21:33:03.417359999 +0300 -@@ -342,9 +342,10 @@ +--- phobos-orig/std/concurrency.d 2010-10-29 05:54:44.000000000 +0400 ++++ phobos/std/concurrency.d 2010-11-07 19:26:52.000000000 +0300 +@@ -359,9 +359,10 @@ owner = ownerTid; fn( args ); } @@ -14,18 +14,18 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. return spawnTid; } diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- phobos-orig/std/conv.d phobos/std/conv.d ---- phobos-orig/std/conv.d 2010-09-17 00:27:48.000000000 +0400 -+++ phobos/std/conv.d 2010-11-04 13:24:59.758325002 +0300 -@@ -1395,7 +1395,7 @@ +--- phobos-orig/std/conv.d 2010-10-29 05:54:44.000000000 +0400 ++++ phobos/std/conv.d 2010-11-08 15:54:33.109464001 +0300 +@@ -1405,7 +1405,7 @@ else // not hex { - if (toupper(p.front) == 'N') + if (toupper(p.front) == 'N' && !startsWithZero) - { + { // nan enforce((p.popFront(), !p.empty && toupper(p.front) == 'A') && (p.popFront(), !p.empty && toupper(p.front) == 'N'), -@@ -3191,6 +3191,11 @@ +@@ -3243,6 +3243,11 @@ T toImpl(T, S)(S d) if (is(Unqual!S == double) && isSomeString!(T)) { //alias Unqual!(ElementType!T) Char; @@ -38,9 +38,9 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. int len = sprintf(buffer.ptr, "%g", d); return to!T(buffer[0 .. len].dup); diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- phobos-orig/std/format.d phobos/std/format.d ---- phobos-orig/std/format.d 2010-09-17 00:27:48.000000000 +0400 -+++ phobos/std/format.d 2010-11-04 18:17:53.483219002 +0300 -@@ -2531,20 +2531,42 @@ +--- phobos-orig/std/format.d 2010-10-29 05:54:44.000000000 +0400 ++++ phobos/std/format.d 2010-11-07 19:26:52.000000000 +0300 +@@ -2582,20 +2582,42 @@ FLprecision = 0x80, } @@ -95,8 +95,8 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. void formatArg(char fc) diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- phobos-orig/std/functional.d phobos/std/functional.d ---- phobos-orig/std/functional.d 2010-09-17 00:27:48.000000000 +0400 -+++ phobos/std/functional.d 2010-10-29 12:01:35.285035001 +0400 +--- phobos-orig/std/functional.d 2010-10-29 05:54:44.000000000 +0400 ++++ phobos/std/functional.d 2010-11-07 19:26:52.000000000 +0300 @@ -713,6 +713,13 @@ assert(dg_pure_nothrow() == 7); //assert(dg_pure_nothrow_safe() == 8); @@ -119,9 +119,9 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. + } } diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- phobos-orig/std/internal/math/biguintx86.d phobos/std/internal/math/biguintx86.d ---- phobos-orig/std/internal/math/biguintx86.d 2010-09-17 00:27:48.000000000 +0400 -+++ phobos/std/internal/math/biguintx86.d 2010-10-26 14:08:51.480925001 +0400 -@@ -733,7 +733,10 @@ +--- phobos-orig/std/internal/math/biguintx86.d 2010-10-29 05:54:44.000000000 +0400 ++++ phobos/std/internal/math/biguintx86.d 2010-11-07 19:26:52.000000000 +0300 +@@ -734,7 +734,10 @@ // EDI = dest // ESI = src @@ -133,7 +133,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. version(D_PIC) { enum { zero = 0 } } else { -@@ -767,7 +770,10 @@ +@@ -768,7 +771,10 @@ jnz L_enter_odd; } // Main loop, with entry point for even length @@ -145,7 +145,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. asm { mov EAX, EBP; // get final carry pop EBP; -@@ -777,6 +783,9 @@ +@@ -778,6 +784,9 @@ ret 5*4; } L_enter_odd: @@ -156,8 +156,8 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. } diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- phobos-orig/std/math.d phobos/std/math.d ---- phobos-orig/std/math.d 2010-09-17 00:27:48.000000000 +0400 -+++ phobos/std/math.d 2010-11-07 17:42:39.390374001 +0300 +--- phobos-orig/std/math.d 2010-10-29 05:54:44.000000000 +0400 ++++ phobos/std/math.d 2010-11-07 19:26:52.000000000 +0300 @@ -276,7 +276,7 @@ assert(abs(71.6Li) == 71.6L); assert(abs(-56) == 56); @@ -308,7 +308,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. /** Compute the value of an integer x, raised to the power of a positive diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- phobos-orig/std/openrj.d phobos/std/openrj.d --- phobos-orig/std/openrj.d 2009-09-03 12:01:40.000000000 +0400 -+++ phobos/std/openrj.d 2010-10-26 13:17:37.480925001 +0400 ++++ phobos/std/openrj.d 2010-10-26 13:17:37.000000000 +0400 @@ -620,11 +620,11 @@ /** * @@ -352,8 +352,8 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch. result = dg(field); diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- phobos-orig/std/outbuffer.d phobos/std/outbuffer.d ---- phobos-orig/std/outbuffer.d 2010-09-17 00:27:48.000000000 +0400 -+++ phobos/std/outbuffer.d 2010-11-05 13:59:42.227267001 +0300 +--- phobos-orig/std/outbuffer.d 2010-10-29 05:54:44.000000000 +0400 ++++ phobos/std/outbuffer.d 2010-11-05 13:59:42.000000000 +0300 @@ -308,8 +308,15 @@ void printf(string format, ...) { diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 67ca541c..a43729a5 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -109,6 +109,7 @@ elseif(D_VERSION EQUAL 2) list(REMOVE_ITEM ZLIB_C ${PHOBOS2_DIR}/etc/c/zlib/minigzip.c ${PHOBOS2_DIR}/etc/c/zlib/example.c + ${PHOBOS2_DIR}/etc/c/zlib/gzio.c ) if(WIN32) file(GLOB PHOBOS2_D_WIN ${PHOBOS2_DIR}/std/windows/*.d)