Skip to content

Commit

Permalink
fix Issue 14040 - Doesn't use assignment in slice
Browse files Browse the repository at this point in the history
If upr has any side effects, lwr should be copied to temporary always.
  • Loading branch information
9rnsr committed Oct 13, 2015
1 parent 18b84b1 commit 4fe170a
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 7 deletions.
26 changes: 19 additions & 7 deletions src/e2ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -4573,12 +4573,23 @@ elem *toElem(Expression *e, IRState *irs)
elem *e = toElem(se->e1, irs);
if (se->lwr)
{
elem *einit = resolveLengthVar(se->lengthVar, &e, t1);
unsigned sz = t1->nextOf()->size();

elem *einit = resolveLengthVar(se->lengthVar, &e, t1);
if (t1->ty == Tsarray)
e = array_toPtr(se->e1->type, e);
if (!einit)
{
einit = e;
e = el_same(&einit);
}
// e is a temporary, typed:
// TYdarray if t->ty == Tarray
// TYptr if t->ty == Tsarray or Tpointer

elem *elwr = toElem(se->lwr, irs);
elem *eupr = toElem(se->upr, irs);
elem *elwr2 = el_same(&elwr);
elem *elwr2 = el_sideeffect(eupr) ? el_copytotmp(&elwr) : el_same(&elwr);
elem *eupr2 = eupr;

//printf("upperIsInBounds = %d lowerIsLessThanUpper = %d\n", se->upperIsInBounds, se->lowerIsLessThanUpper);
Expand Down Expand Up @@ -4641,31 +4652,32 @@ elem *toElem(Expression *e, IRState *irs)
elwr = el_combine(elwr, eb);
}
}
if (t1->ty != Tsarray)
e = array_toPtr(se->e1->type, e);

// Create an array reference where:
// length is (upr - lwr)
// pointer is (ptr + lwr*sz)
// Combine as (length pair ptr)

e = array_toPtr(se->e1->type, e);

elem *eofs = el_bin(OPmul, TYsize_t, elwr2, el_long(TYsize_t, sz));
elem *eptr = el_bin(OPadd, TYnptr, el_same(&e), eofs);
elem *eptr = el_bin(OPadd, TYnptr, e, eofs);

if (tb->ty == Tarray)
{
elem *elen = el_bin(OPmin, TYsize_t, eupr2, el_copytree(elwr2));
e = el_combine(e, el_pair(TYdarray, elen, eptr));
e = el_pair(TYdarray, elen, eptr);
}
else
{
assert(tb->ty == Tsarray);
e = el_una(OPind, totym(se->type), el_combine(e, eptr));
e = el_una(OPind, totym(se->type), eptr);
if (tybasic(e->Ety) == TYstruct)
e->ET = Type_toCtype(se->type);
}
e = el_combine(elwr, e);
e = el_combine(einit, e);
//elem_print(e);
}
else if (t1->ty == Tsarray && tb->ty == Tarray)
{
Expand Down
30 changes: 30 additions & 0 deletions test/runnable/evalorder.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
extern(C) int printf(const char*, ...);

void test14040()
{
uint[] values = [0, 1, 2, 3, 4, 5, 6, 7];
uint offset = 0;

auto a1 = values[offset .. offset += 2];
if (a1 != [0, 1] || offset != 2)
assert(0);

uint[] fun()
{
offset += 2;
return values;
}
auto a2 = fun()[offset .. offset += 2];
if (a2 != [4, 5] || offset != 6)
assert(0);
}

/******************************************/

int main()
{
test14040();

printf("Success\n");
return 0;
}

0 comments on commit 4fe170a

Please sign in to comment.