From 349305cd1d471402fb8eef5c4d154ab30a201dcf Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Fri, 14 Jun 2013 17:02:41 +0200 Subject: [PATCH] Fix array op argument evaluation order regression. Fixes DMD testcase 'arrayop'. --- dmd2/arrayop.c | 3 +++ gen/tocall.cpp | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/dmd2/arrayop.c b/dmd2/arrayop.c index a2e38e4a..d0bad81a 100644 --- a/dmd2/arrayop.c +++ b/dmd2/arrayop.c @@ -255,7 +255,10 @@ ArrayOp *buildArrayOp(Identifier *ident, BinExp *exp, Scope *sc, Loc loc) Parameters *fparams = new Parameters(); Expression *loopbody = exp->buildArrayLoop(fparams); if (isDruntimeArrayOp(ident)) + { op->cFunc = FuncDeclaration::genCfunc(fparams, exp->type, ident); + op->cFunc->isArrayOp = 2; + } #else if (isDruntimeArrayOp(ident)) op->cFunc = FuncDeclaration::genCfunc(exp->type, ident); diff --git a/gen/tocall.cpp b/gen/tocall.cpp index 6d16cf8f..257d32c1 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -513,7 +513,10 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* std::vector argvals; argvals.reserve(n); if (dfnval && dfnval->func->isArrayOp) { - // slightly different approach for array operators + // For array ops, the druntime implementation signatures are crafted + // specifically such that the evaluation order is as expected with + // the strange DMD reverse parameter passing order. Thus, we need + // to actually build the arguments right-to-left for them. for (int i=n-1; i>=0; --i) { Parameter* fnarg = Parameter::getNth(tf->parameters, i); assert(fnarg);