Support implicit casts in DtoArrayPtr()

On branch merge-2.068, `runnable/testassign.d` checks that a dynamic
array of objects of type B can be assigned to a dynamic array of objects
of a base class A.
The front-end seems to modify the rhs expression type from B[] to A[],
so we need to perform an implicit cast in DtoArrayPtr() to prevent
further type mismatches, notably in DtoArrayAssign().
This commit is contained in:
Martin 2015-10-03 21:07:55 +02:00
parent 907c3464d9
commit d30310c1f9

View file

@ -167,9 +167,6 @@ static void DtoArrayInit(Loc& loc, LLValue* ptr, LLValue* length, DValue* dvalue
gIR->scope() = IRScope(bodybb);
LLValue* itr_val = DtoLoad(itr);
/* bitcopy element
//DtoMemCpy(DtoGEP1(ptr, itr_val), dvalue->getLVal(), elementSize);
*/
// assign array element value
DValue *arrayelem = new DVarValue(dvalue->type->toBasetype(), DtoGEP1(ptr, itr_val, "arrayinit.arrayelem"));
DtoAssign(loc, arrayelem, dvalue, op);
@ -1060,22 +1057,32 @@ LLValue* DtoArrayPtr(DValue* v)
LOG_SCOPE;
Type* t = v->getType()->toBasetype();
if (t->ty == Tarray) {
// v's LL array element type may not be the real one
// due to implicit casts (e.g., to base class)
LLType* wantedLLPtrType = DtoPtrToType(t->nextOf());
LLValue* ptr = NULL;
if (t->ty == Tarray)
{
if (DSliceValue* s = v->isSlice())
return s->ptr;
ptr = s->ptr;
else if (v->isNull())
return getNullPtr(DtoPtrToType(t->nextOf()));
ptr = getNullPtr(wantedLLPtrType);
else if (v->isLVal())
return DtoLoad(DtoGEPi(v->getLVal(), 0,1), ".ptr");
return gIR->ir->CreateExtractValue(v->getRVal(), 1, ".ptr");
ptr = DtoLoad(DtoGEPi(v->getLVal(), 0, 1), ".ptr");
else
ptr = gIR->ir->CreateExtractValue(v->getRVal(), 1, ".ptr");
}
else if (t->ty == Tsarray) {
else if (t->ty == Tsarray)
{
assert(!v->isSlice());
assert(!v->isNull());
return DtoGEPi(v->getRVal(), 0, 0, "sarrayptr");
ptr = DtoGEPi(v->getRVal(), 0, 0, "sarrayptr");
}
else
llvm_unreachable("Unexpected array type.");
llvm_unreachable("Unexpected array type.");
return DtoBitCast(ptr, wantedLLPtrType);
}
//////////////////////////////////////////////////////////////////////////////////////////