From 3af4bc2ed6174d870f394def354810ed32be0d4e Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 15 Jun 2016 23:16:46 +0200 Subject: [PATCH] Fix evaluation/load order of binary operators Fixes issue #1327 by loading immediately from lvalues resulting from left- and right-hand sides. --- gen/binops.cpp | 39 +++++++++++++++++++-------------------- gen/complex.cpp | 12 ++++++------ gen/complex.h | 14 +++++++------- gen/llvmhelpers.h | 10 +++++----- gen/toir.cpp | 30 +++++++++++++++--------------- 5 files changed, 52 insertions(+), 53 deletions(-) diff --git a/gen/binops.cpp b/gen/binops.cpp index 278226632d2..785848b7da9 100644 --- a/gen/binops.cpp +++ b/gen/binops.cpp @@ -18,11 +18,10 @@ ////////////////////////////////////////////////////////////////////////////// -DValue *DtoBinAdd(DValue *lhs, DValue *rhs) { +DImValue *DtoBinAdd(DRValue *lhs, DRValue *rhs) { Type *t = lhs->type; - LLValue *l, *r; - l = DtoRVal(lhs); - r = DtoRVal(rhs); + LLValue *l = DtoRVal(lhs); + LLValue *r = DtoRVal(rhs); LLValue *res; if (t->isfloating()) { @@ -36,11 +35,10 @@ DValue *DtoBinAdd(DValue *lhs, DValue *rhs) { ////////////////////////////////////////////////////////////////////////////// -DValue *DtoBinSub(DValue *lhs, DValue *rhs) { +DImValue *DtoBinSub(DRValue *lhs, DRValue *rhs) { Type *t = lhs->type; - LLValue *l, *r; - l = DtoRVal(lhs); - r = DtoRVal(rhs); + LLValue *l = DtoRVal(lhs); + LLValue *r = DtoRVal(rhs); LLValue *res; if (t->isfloating()) { @@ -54,11 +52,10 @@ DValue *DtoBinSub(DValue *lhs, DValue *rhs) { ////////////////////////////////////////////////////////////////////////////// -DValue *DtoBinMul(Type *targettype, DValue *lhs, DValue *rhs) { +DImValue *DtoBinMul(Type *targettype, DRValue *lhs, DRValue *rhs) { Type *t = lhs->type; - LLValue *l, *r; - l = DtoRVal(lhs); - r = DtoRVal(rhs); + LLValue *l = DtoRVal(lhs); + LLValue *r = DtoRVal(rhs); LLValue *res; if (t->isfloating()) { @@ -66,16 +63,16 @@ DValue *DtoBinMul(Type *targettype, DValue *lhs, DValue *rhs) { } else { res = gIR->ir->CreateMul(l, r); } + return new DImValue(targettype, res); } ////////////////////////////////////////////////////////////////////////////// -DValue *DtoBinDiv(Type *targettype, DValue *lhs, DValue *rhs) { +DImValue *DtoBinDiv(Type *targettype, DRValue *lhs, DRValue *rhs) { Type *t = lhs->type; - LLValue *l, *r; - l = DtoRVal(lhs); - r = DtoRVal(rhs); + LLValue *l = DtoRVal(lhs); + LLValue *r = DtoRVal(rhs); LLValue *res; if (t->isfloating()) { @@ -85,16 +82,17 @@ DValue *DtoBinDiv(Type *targettype, DValue *lhs, DValue *rhs) { } else { res = gIR->ir->CreateUDiv(l, r); } + return new DImValue(targettype, res); } ////////////////////////////////////////////////////////////////////////////// -DValue *DtoBinRem(Type *targettype, DValue *lhs, DValue *rhs) { +DImValue *DtoBinRem(Type *targettype, DRValue *lhs, DRValue *rhs) { Type *t = lhs->type; - LLValue *l, *r; - l = DtoRVal(lhs); - r = DtoRVal(rhs); + LLValue *l = DtoRVal(lhs); + LLValue *r = DtoRVal(rhs); + LLValue *res; if (t->isfloating()) { res = gIR->ir->CreateFRem(l, r); @@ -103,6 +101,7 @@ DValue *DtoBinRem(Type *targettype, DValue *lhs, DValue *rhs) { } else { res = gIR->ir->CreateURem(l, r); } + return new DImValue(targettype, res); } diff --git a/gen/complex.cpp b/gen/complex.cpp index fd4f226e820..2ed90febeb4 100644 --- a/gen/complex.cpp +++ b/gen/complex.cpp @@ -181,7 +181,7 @@ void DtoGetComplexParts(Loc &loc, Type *to, DValue *val, LLValue *&re, //////////////////////////////////////////////////////////////////////////////// -DValue *DtoComplexAdd(Loc &loc, Type *type, DValue *lhs, DValue *rhs) { +DImValue *DtoComplexAdd(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) { llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; // lhs values @@ -212,7 +212,7 @@ DValue *DtoComplexAdd(Loc &loc, Type *type, DValue *lhs, DValue *rhs) { //////////////////////////////////////////////////////////////////////////////// -DValue *DtoComplexSub(Loc &loc, Type *type, DValue *lhs, DValue *rhs) { +DImValue *DtoComplexSub(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) { llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; // lhs values @@ -243,7 +243,7 @@ DValue *DtoComplexSub(Loc &loc, Type *type, DValue *lhs, DValue *rhs) { //////////////////////////////////////////////////////////////////////////////// -DValue *DtoComplexMul(Loc &loc, Type *type, DValue *lhs, DValue *rhs) { +DImValue *DtoComplexMul(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) { llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; // lhs values @@ -296,7 +296,7 @@ DValue *DtoComplexMul(Loc &loc, Type *type, DValue *lhs, DValue *rhs) { //////////////////////////////////////////////////////////////////////////////// -DValue *DtoComplexDiv(Loc &loc, Type *type, DValue *lhs, DValue *rhs) { +DImValue *DtoComplexDiv(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) { llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; // lhs values @@ -369,7 +369,7 @@ DValue *DtoComplexDiv(Loc &loc, Type *type, DValue *lhs, DValue *rhs) { //////////////////////////////////////////////////////////////////////////////// -DValue *DtoComplexRem(Loc &loc, Type *type, DValue *lhs, DValue *rhs) { +DImValue *DtoComplexRem(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) { llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im, *divisor; // lhs values @@ -390,7 +390,7 @@ DValue *DtoComplexRem(Loc &loc, Type *type, DValue *lhs, DValue *rhs) { //////////////////////////////////////////////////////////////////////////////// -DValue *DtoComplexNeg(Loc &loc, Type *type, DValue *val) { +DImValue *DtoComplexNeg(Loc &loc, Type *type, DRValue *val) { llvm::Value *a, *b, *re, *im; // values diff --git a/gen/complex.h b/gen/complex.h index b3c58b95350..a673dc7d80b 100644 --- a/gen/complex.h +++ b/gen/complex.h @@ -16,8 +16,8 @@ #include "tokens.h" #include "longdouble.h" +#include "dvalue.h" -class DValue; struct Loc; class Type; namespace llvm { @@ -43,12 +43,12 @@ void DtoGetComplexParts(Loc &loc, Type *to, DValue *c, DValue *&re, void DtoGetComplexParts(Loc &loc, Type *to, DValue *c, llvm::Value *&re, llvm::Value *&im); -DValue *DtoComplexAdd(Loc &loc, Type *type, DValue *lhs, DValue *rhs); -DValue *DtoComplexSub(Loc &loc, Type *type, DValue *lhs, DValue *rhs); -DValue *DtoComplexMul(Loc &loc, Type *type, DValue *lhs, DValue *rhs); -DValue *DtoComplexDiv(Loc &loc, Type *type, DValue *lhs, DValue *rhs); -DValue *DtoComplexRem(Loc &loc, Type *type, DValue *lhs, DValue *rhs); -DValue *DtoComplexNeg(Loc &loc, Type *type, DValue *val); +DImValue *DtoComplexAdd(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs); +DImValue *DtoComplexSub(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs); +DImValue *DtoComplexMul(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs); +DImValue *DtoComplexDiv(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs); +DImValue *DtoComplexRem(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs); +DImValue *DtoComplexNeg(Loc &loc, Type *type, DRValue *val); llvm::Value *DtoComplexEquals(Loc &loc, TOK op, DValue *lhs, DValue *rhs); diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index ff51b82510e..8c725f1708e 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -129,13 +129,13 @@ LLConstant *DtoConstExpInit(Loc &loc, Type *targetType, Expression *exp); LLConstant *DtoTypeInfoOf(Type *ty, bool base = true); // binary operations -DValue *DtoBinAdd(DValue *lhs, DValue *rhs); -DValue *DtoBinSub(DValue *lhs, DValue *rhs); +DImValue *DtoBinAdd(DRValue *lhs, DRValue *rhs); +DImValue *DtoBinSub(DRValue *lhs, DRValue *rhs); // these binops need an explicit result type to handling // to give 'ifloat op float' and 'float op ifloat' the correct type -DValue *DtoBinMul(Type *resulttype, DValue *lhs, DValue *rhs); -DValue *DtoBinDiv(Type *resulttype, DValue *lhs, DValue *rhs); -DValue *DtoBinRem(Type *resulttype, DValue *lhs, DValue *rhs); +DImValue *DtoBinMul(Type *resulttype, DRValue *lhs, DRValue *rhs); +DImValue *DtoBinDiv(Type *resulttype, DRValue *lhs, DRValue *rhs); +DImValue *DtoBinRem(Type *resulttype, DRValue *lhs, DRValue *rhs); LLValue *DtoBinNumericEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op); LLValue *DtoBinFloatsEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op); diff --git a/gen/toir.cpp b/gen/toir.cpp index b8b4289e4a9..f65df2d98bf 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -766,7 +766,7 @@ class ToElemVisitor : public Visitor { e->type->toChars()); LOG_SCOPE; - DValue *l = toElem(e->e1); + DRValue *l = toElem(e->e1)->getRVal(); Type *t = e->type->toBasetype(); Type *e1type = e->e1->type->toBasetype(); @@ -778,9 +778,9 @@ class ToElemVisitor : public Visitor { Logger::println("Adding integer to pointer"); result = emitPointerOffset(p, e->loc, l, e->e2, false, e->type); } else if (t->iscomplex()) { - result = DtoComplexAdd(e->loc, e->type, l, toElem(e->e2)); + result = DtoComplexAdd(e->loc, e->type, l, toElem(e->e2)->getRVal()); } else { - result = DtoBinAdd(l, toElem(e->e2)); + result = DtoBinAdd(l, toElem(e->e2)->getRVal()); } } @@ -789,7 +789,7 @@ class ToElemVisitor : public Visitor { e->type->toChars()); LOG_SCOPE; - DValue *l = toElem(e->e1); + DRValue *l = toElem(e->e1)->getRVal(); Type *t = e->type->toBasetype(); Type *t1 = e->e1->type->toBasetype(); @@ -812,9 +812,9 @@ class ToElemVisitor : public Visitor { Logger::println("Subtracting integer from pointer"); result = emitPointerOffset(p, e->loc, l, e->e2, true, e->type); } else if (t->iscomplex()) { - result = DtoComplexSub(e->loc, e->type, l, toElem(e->e2)); + result = DtoComplexSub(e->loc, e->type, l, toElem(e->e2)->getRVal()); } else { - result = DtoBinSub(l, toElem(e->e2)); + result = DtoBinSub(l, toElem(e->e2)->getRVal()); } } @@ -825,8 +825,8 @@ class ToElemVisitor : public Visitor { e->type->toChars()); LOG_SCOPE; - DValue *l = toElem(e->e1); - DValue *r = toElem(e->e2); + DRValue *l = toElem(e->e1)->getRVal(); + DRValue *r = toElem(e->e2)->getRVal(); errorOnIllegalArrayOp(e, e->e1, e->e2); @@ -844,8 +844,8 @@ class ToElemVisitor : public Visitor { e->type->toChars()); LOG_SCOPE; - DValue *l = toElem(e->e1); - DValue *r = toElem(e->e2); + DRValue *l = toElem(e->e1)->getRVal(); + DRValue *r = toElem(e->e2)->getRVal(); errorOnIllegalArrayOp(e, e->e1, e->e2); @@ -863,8 +863,8 @@ class ToElemVisitor : public Visitor { e->type->toChars()); LOG_SCOPE; - DValue *l = toElem(e->e1); - DValue *r = toElem(e->e2); + DRValue *l = toElem(e->e1)->getRVal(); + DRValue *r = toElem(e->e2)->getRVal(); errorOnIllegalArrayOp(e, e->e1, e->e2); @@ -2320,14 +2320,14 @@ class ToElemVisitor : public Visitor { e->type->toChars()); LOG_SCOPE; - DValue *l = toElem(e->e1); + DRValue *dval = toElem(e->e1)->getRVal(); if (e->type->iscomplex()) { - result = DtoComplexNeg(e->loc, e->type, l); + result = DtoComplexNeg(e->loc, e->type, dval); return; } - LLValue *val = DtoRVal(l); + LLValue *val = DtoRVal(dval); if (e->type->isintegral()) { val = p->ir->CreateNeg(val, "negval");