From d30310c1f92b3bdb19e4316de2bc8ece5f66ede2 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 3 Oct 2015 21:07:55 +0200 Subject: [PATCH] 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(). --- gen/arrays.cpp | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 7e84e94182..cf2c0fd2ee 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -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); } //////////////////////////////////////////////////////////////////////////////////////////