Apply patch from klickverbot. This is his 'proper fix' patch for bug #395.

This commit is contained in:
Kelly Wilson 2010-03-08 23:37:40 -07:00
parent 902bc06fb1
commit b38845e88e
6 changed files with 45 additions and 51 deletions

View file

@ -14,41 +14,6 @@
#include "gen/dvalue.h" #include "gen/dvalue.h"
#include "ir/irmodule.h" #include "ir/irmodule.h"
// makes sure the key value lives in memory so it can be passed to the runtime functions without problems
// returns the pointer
static LLValue* to_pkey(Loc& loc, DValue* key)
{
Type* keytype = key->getType();
bool needmem = !DtoIsPassedByRef(keytype);
LLValue* pkey;
if (key->isIm()) {
pkey = key->getRVal();
}
else if (DVarValue* var = key->isVar()) {
pkey = key->getLVal();
needmem = false;
}
else if (key->isConst()) {
needmem = true;
pkey = key->getRVal();
}
else {
LLValue* tmp = DtoAlloca(keytype, "aatmpkeystorage");
DVarValue var(keytype, tmp);
DtoAssign(loc, &var, key);
return tmp;
}
// give memory
if (needmem) {
LLValue* tmp = DtoAlloca(keytype, "aatmpkeystorage");
DtoStore(pkey, tmp);
pkey = tmp;
}
return pkey;
}
// returns the keytype typeinfo // returns the keytype typeinfo
static LLValue* to_keyti(DValue* key) static LLValue* to_keyti(DValue* key)
{ {
@ -79,7 +44,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
keyti = DtoBitCast(keyti, funcTy->getParamType(1)); keyti = DtoBitCast(keyti, funcTy->getParamType(1));
// pkey param // pkey param
LLValue* pkey = to_pkey(loc, key); LLValue* pkey = makeLValue(loc, key);
pkey = DtoBitCast(pkey, funcTy->getParamType(lvalue ? 3 : 2)); pkey = DtoBitCast(pkey, funcTy->getParamType(lvalue ? 3 : 2));
// call runtime // call runtime
@ -164,7 +129,7 @@ DValue* DtoAAIn(Loc& loc, Type* type, DValue* aa, DValue* key)
keyti = DtoBitCast(keyti, funcTy->getParamType(1)); keyti = DtoBitCast(keyti, funcTy->getParamType(1));
// pkey param // pkey param
LLValue* pkey = to_pkey(loc, key); LLValue* pkey = makeLValue(loc, key);
pkey = DtoBitCast(pkey, funcTy->getParamType(2)); pkey = DtoBitCast(pkey, funcTy->getParamType(2));
// call runtime // call runtime
@ -206,7 +171,7 @@ void DtoAARemove(Loc& loc, DValue* aa, DValue* key)
keyti = DtoBitCast(keyti, funcTy->getParamType(1)); keyti = DtoBitCast(keyti, funcTy->getParamType(1));
// pkey param // pkey param
LLValue* pkey = to_pkey(loc, key); LLValue* pkey = makeLValue(loc, key);
pkey = DtoBitCast(pkey, funcTy->getParamType(2)); pkey = DtoBitCast(pkey, funcTy->getParamType(2));
// build arg vector // build arg vector

View file

@ -532,23 +532,14 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
void DtoCatAssignElement(Type* arrayType, DValue* array, Expression* exp) void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* exp)
{ {
Logger::println("DtoCatAssignElement"); Logger::println("DtoCatAssignElement");
LOG_SCOPE; LOG_SCOPE;
assert(array); assert(array);
DValue *expVal = exp->toElem(gIR); LLValue *valueToAppend = makeLValue(loc, exp->toElem(gIR));
LLValue *valueToAppend;
if (expVal->isLVal())
valueToAppend = expVal->getLVal();
else {
valueToAppend = DtoAlloca(expVal->getType(), ".appendingElementOnStack");
DVarValue lval(expVal->getType(), valueToAppend);
Loc loc;
DtoAssign(loc, &lval, expVal);
}
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcT"); LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcT");
LLSmallVector<LLValue*,3> args; LLSmallVector<LLValue*,3> args;

View file

@ -24,7 +24,7 @@ DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool default
DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size_t ndims, bool defaultInit=true); DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size_t ndims, bool defaultInit=true);
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim); DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim);
void DtoCatAssignElement(Type* type, DValue* arr, Expression* exp); void DtoCatAssignElement(Loc& loc, Type* type, DValue* arr, Expression* exp);
DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp); DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp);
DSliceValue* DtoCatArrays(Type* type, Expression* e1, Expression* e2); DSliceValue* DtoCatArrays(Type* type, Expression* e1, Expression* e2);
DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2); DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2);

View file

@ -1572,3 +1572,36 @@ Type * stripModifiers( Type * type )
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
LLValue* makeLValue(Loc& loc, DValue* value)
{
Type* valueType = value->getType();
bool needsMemory;
LLValue* valuePointer;
if (value->isIm()) {
valuePointer = value->getRVal();
needsMemory = !DtoIsPassedByRef(valueType);
}
else if (DVarValue* var = value->isVar()) {
valuePointer = value->getLVal();
needsMemory = false;
}
else if (value->isConst()) {
valuePointer = value->getRVal();
needsMemory = true;
}
else {
valuePointer = DtoAlloca(valueType, ".makelvaluetmp");
DVarValue var(valueType, valuePointer);
DtoAssign(loc, &var, value);
needsMemory = false;
}
if (needsMemory) {
LLValue* tmp = DtoAlloca(valueType, ".makelvaluetmp");
DtoStore(valuePointer, tmp);
valuePointer = tmp;
}
return valuePointer;
}

View file

@ -146,6 +146,11 @@ IrModule* getIrModule(Module* M);
/// Returns the offset rounded up to the closest safely aligned offset. /// Returns the offset rounded up to the closest safely aligned offset.
size_t realignOffset(size_t offset, Type* type); size_t realignOffset(size_t offset, Type* type);
/// Returns the llvm::Value of the passed DValue, making sure that it is an
/// lvalue (has a memory address), so it can be passed to the D runtime
/// functions without problems.
LLValue* makeLValue(Loc& loc, DValue* value);
//////////////////////////////////////////// ////////////////////////////////////////////
// gen/tocall.cpp stuff below // gen/tocall.cpp stuff below
//////////////////////////////////////////// ////////////////////////////////////////////

View file

@ -2234,7 +2234,7 @@ DValue* CatAssignExp::toElem(IRState* p)
Type* e2type = e2->type->toBasetype(); Type* e2type = e2->type->toBasetype();
if (e2type == elemtype) { if (e2type == elemtype) {
DtoCatAssignElement(e1type, l, e2); DtoCatAssignElement(loc, e1type, l, e2);
} }
else if (e1type == e2type) { else if (e1type == e2type) {
DSliceValue* slice = DtoCatAssignArray(l,e2); DSliceValue* slice = DtoCatAssignArray(l,e2);