Skip to content

Commit

Permalink
Merge pull request #4736 from 9rnsr/fix14672
Browse files Browse the repository at this point in the history
[REG2.067.0] Issue 14672 - Internal error: e2ir.c 4620 when copying array of derived class to an array of base class
  • Loading branch information
WalterBright committed Jun 12, 2015
2 parents d199239 + 306e7b1 commit c30cddf
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
7 changes: 6 additions & 1 deletion src/e2ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -4654,7 +4654,12 @@ elem *toElem(Expression *e, IRState *irs)
else
{
assert(t1->ty == tb->ty); // Tarray or Tsarray
assert(t1->nextOf()->equivalent(tb->nextOf()));

// Bugzilla 14672: If se is in left side operand of element-wise
// assignment, the element type can be painted to the base class.
int offset;
assert(t1->nextOf()->equivalent(tb->nextOf()) ||
tb->nextOf()->isBaseOf(t1->nextOf(), &offset) && offset == 0);
}
el_setLoc(e, se->loc);
result = e;
Expand Down
37 changes: 36 additions & 1 deletion test/runnable/testassign.d
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,41 @@ void test12500()
++foo *= 1.5; // Rewrite to: (foo += 1) *= 1.5;
}

/***************************************************/
// 14672

void test14672()
{
interface I {}

class B {}
class D : B, I {}

D d = new D();
D[] da = [d];
B[] ba = [null];
I[] ia = [null];

// ba and da points different payloads,
// so element-wise assignment should work.
ba[] = da[]; // OK <- e2ir ICE
assert(ba[0] is d);

// Today element-wise assignment is implemented as memcpy, For that reason
// the conversion from derived classes to base interfaces is disallowed
// because it requries offset adjustments.
static assert(!__traits(compiles, { ia[] = da[]; }));

// after the assignment, ba will wongly point the payload of da,
// that's typed as D[]. To aboid type system breaking, it's disallowed.
static assert(!__traits(compiles, { ba = da; }));

// the assigned array literal is a new payload,
// so rebinding ba should work.
ba = [d]; // OK
assert(ba[0] is d);
}

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

int main()
Expand Down Expand Up @@ -1123,8 +1158,8 @@ int main()
test12212();
test12650();
test13044();

test12500();
test14672();

printf("Success\n");
return 0;
Expand Down

0 comments on commit c30cddf

Please sign in to comment.