# HG changeset patch # User Leandro Lucarella # Date 1262801899 10800 # Node ID 1d5721f9ae183a5b8abf9c14fce9f78ac6de81a4 # Parent 2afcaab30a6a94c1bc4eb0095e1a3acb3ce19a1b [WIP] Merge DMD r251: bugzilla 111 (appending a dchar to a char[]) This patch needs some work in the code generation, because of the runtime changes (functions "_d_arrayappendcd" and "_d_arrayappendwd" are added). This doesn't affect existing code though, it just makes with patch a little useless, because something like this: char [] s; s ~= '\u6211'; That failed to compile with a nice error message previously to this change, now fails with and ugly error message (a failed assertion). Apparently there is a regression introduced by this patch too, when compiling Dil I get this assertion message: ldc: /home/luca/tesis/ldc/gen/statements.cpp:132: virtual void ReturnStatement::toIR(IRState*): Assertion `p->topfunc()->getReturnType() == llvm::Type::getVoidTy(gIR->context())' failed. 0 ldc 0x08a91628 Thank god we have bisecting capabilities in VCSs now ;) --- dmd/expression.c | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 41 insertions(+), 6 deletions(-) diff -r 2afcaab30a6a -r 1d5721f9ae18 dmd/expression.c --- a/dmd/expression.c Wed Jan 06 15:18:19 2010 -0300 +++ b/dmd/expression.c Wed Jan 06 15:18:19 2010 -0300 @@ -8420,10 +8420,15 @@ e2->rvalue(); + Type *tb1next = tb1->nextOf(); + if ((tb1->ty == Tarray) && (tb2->ty == Tarray || tb2->ty == Tsarray) && - e2->implicitConvTo(e1->type) - //e1->type->next->equals(e2->type->next) + (e2->implicitConvTo(e1->type) +#if DMDV2 + || tb2->nextOf()->implicitConvTo(tb1next) +#endif + ) ) { // Append array e2 = e2->castTo(sc, e1->type); @@ -8431,18 +8436,30 @@ e = this; } else if ((tb1->ty == Tarray) && - e2->implicitConvTo(tb1->nextOf()) + e2->implicitConvTo(tb1next) ) { // Append element - e2 = e2->castTo(sc, tb1->nextOf()); + e2 = e2->castTo(sc, tb1next); type = e1->type; e = this; } + else if (tb1->ty == Tarray && + (tb1next->ty == Tchar || tb1next->ty == Twchar) && + e2->implicitConvTo(Type::tdchar) + ) + { // Append dchar to char[] or wchar[] + e2 = e2->castTo(sc, Type::tdchar); + type = e1->type; + e = this; + + /* Do not allow appending wchar to char[] because if wchar happens + * to be a surrogate pair, nothing good can result. + */ + } else { error("cannot append type %s to type %s", tb2->toChars(), tb1->toChars()); - type = Type::tint32; - e = this; + e = new ErrorExp(); } return e; } @@ -8464,6 +8481,15 @@ if (e) return e; +#if DMDV2 + if (e1->op == TOKarraylength) + { + e = ArrayLengthExp::rewriteOpAssign(this); + e = e->semantic(sc); + return e; + } +#endif + if (e1->op == TOKslice) { // T[] -= ... typeCombine(sc); @@ -8531,6 +8557,15 @@ if (e) return e; +#if DMDV2 + if (e1->op == TOKarraylength) + { + e = ArrayLengthExp::rewriteOpAssign(this); + e = e->semantic(sc); + return e; + } +#endif + if (e1->op == TOKslice) { // T[] -= ... typeCombine(sc);