mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 09:00:33 +03:00
arrays: Fix distinction between full and element-wise assignment
If both lhs and rhs are static/dynamic arrays, simply compare the LL types produced by DtoArrayPtr(). If they mach, use full array assignment, otherwise treat the rhs as compatible element (e.g., T for T[n], T[n][], T[n][m], or even T[a][b] for T[a][b][c][] :D).
This commit is contained in:
parent
eb96b8ab44
commit
daee7955d5
1 changed files with 10 additions and 6 deletions
|
@ -259,9 +259,13 @@ void DtoArrayAssign(Loc& loc, DValue* lhs, DValue* rhs, int op, bool canSkipPost
|
||||||
const bool needsDestruction = (!isConstructing && elemType->needsDestruction());
|
const bool needsDestruction = (!isConstructing && elemType->needsDestruction());
|
||||||
const bool needsPostblit = (op != TOKblit && !canSkipPostblit && arrayNeedsPostblit(t));
|
const bool needsPostblit = (op != TOKblit && !canSkipPostblit && arrayNeedsPostblit(t));
|
||||||
|
|
||||||
LLValue* lhsPtr = DtoBitCast(DtoArrayPtr(lhs), getVoidPtrType());
|
LLValue* realLhsPtr = DtoArrayPtr(lhs);
|
||||||
|
LLValue* lhsPtr = DtoBitCast(realLhsPtr, getVoidPtrType());
|
||||||
LLValue* lhsLength = DtoArrayLen(lhs);
|
LLValue* lhsLength = DtoArrayLen(lhs);
|
||||||
|
|
||||||
|
LLValue* realRhsArrayPtr =
|
||||||
|
(t2->ty == Tarray || t2->ty == Tsarray ? DtoArrayPtr(rhs) : NULL);
|
||||||
|
|
||||||
// TODO: This should use AssignExp::ismemset.
|
// TODO: This should use AssignExp::ismemset.
|
||||||
// Disallow void array block assignment (DMD issue 7493).
|
// Disallow void array block assignment (DMD issue 7493).
|
||||||
bool canBeBlockAssignment = true;
|
bool canBeBlockAssignment = true;
|
||||||
|
@ -274,11 +278,12 @@ void DtoArrayAssign(Loc& loc, DValue* lhs, DValue* rhs, int op, bool canSkipPost
|
||||||
}
|
}
|
||||||
canBeBlockAssignment = leafElemType->ty != Tvoid;
|
canBeBlockAssignment = leafElemType->ty != Tvoid;
|
||||||
}
|
}
|
||||||
if (!t2->implicitConvTo(t->nextOf()) || !canBeBlockAssignment)
|
if ((realRhsArrayPtr && realLhsPtr->getType() == realRhsArrayPtr->getType()) ||
|
||||||
|
!canBeBlockAssignment)
|
||||||
{
|
{
|
||||||
// T[] = T[] T[] = T[n]
|
// T[] = T[] T[] = T[n]
|
||||||
// T[n] = T[n] T[n] = T[]
|
// T[n] = T[n] T[n] = T[]
|
||||||
LLValue* rhsPtr = DtoBitCast(DtoArrayPtr(rhs), getVoidPtrType());
|
LLValue* rhsPtr = DtoBitCast(realRhsArrayPtr, getVoidPtrType());
|
||||||
LLValue* rhsLength = DtoArrayLen(rhs);
|
LLValue* rhsLength = DtoArrayLen(rhs);
|
||||||
|
|
||||||
if (!needsDestruction && !needsPostblit)
|
if (!needsDestruction && !needsPostblit)
|
||||||
|
@ -333,13 +338,12 @@ void DtoArrayAssign(Loc& loc, DValue* lhs, DValue* rhs, int op, bool canSkipPost
|
||||||
if (!needsDestruction && !needsPostblit)
|
if (!needsDestruction && !needsPostblit)
|
||||||
{
|
{
|
||||||
// fast version
|
// fast version
|
||||||
LLValue* elemSize = DtoConstSize_t(getTypePaddedSize(i1ToI8(voidToI8(DtoType(elemType)))));
|
LLValue* elemSize = DtoConstSize_t(getTypePaddedSize(realLhsPtr->getType()->getContainedType(0)));
|
||||||
LLValue* lhsSize = gIR->ir->CreateMul(elemSize, lhsLength);
|
LLValue* lhsSize = gIR->ir->CreateMul(elemSize, lhsLength);
|
||||||
LLType* rhsType = i1ToI8(voidToI8(DtoType(t2)));
|
LLType* rhsType = i1ToI8(voidToI8(DtoType(t2)));
|
||||||
LLValue* rhsSize = DtoConstSize_t(getTypePaddedSize(rhsType));
|
LLValue* rhsSize = DtoConstSize_t(getTypePaddedSize(rhsType));
|
||||||
LLValue* actualLength = gIR->ir->CreateExactUDiv(lhsSize, rhsSize);
|
|
||||||
|
|
||||||
LLValue* actualPtr = DtoBitCast(lhsPtr, rhsType->getPointerTo());
|
LLValue* actualPtr = DtoBitCast(lhsPtr, rhsType->getPointerTo());
|
||||||
|
LLValue* actualLength = gIR->ir->CreateExactUDiv(lhsSize, rhsSize);
|
||||||
DtoArrayInit(loc, actualPtr, actualLength, rhs, op);
|
DtoArrayInit(loc, actualPtr, actualLength, rhs, op);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue