From caa61a55236709db23d2d0ae178c0673b0f2f066 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 29 Jul 2008 12:32:01 +0200 Subject: [PATCH] Error if static array is cast to an array such that oldarraysize % newelemsize != 0. --- gen/arrays.cpp | 26 +++++++++++++++++--------- gen/arrays.h | 6 +++--- gen/llvmhelpers.cpp | 2 +- gen/toir.cpp | 4 ++-- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 8a650b7d..a3a42aca 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -672,7 +672,7 @@ DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2) ////////////////////////////////////////////////////////////////////////////////////////// // helper for eq and cmp -static LLValue* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti) +static LLValue* DtoArrayEqCmp_impl(Loc& loc, const char* func, DValue* l, DValue* r, bool useti) { Logger::println("comparing arrays"); LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, func); @@ -689,9 +689,9 @@ static LLValue* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool if ((l_ty->ty == Tsarray) || (r_ty->ty == Tsarray)) { Type* a_ty = l_ty->next->arrayOf(); if (l_ty->ty == Tsarray) - l = DtoCastArray(l, a_ty); + l = DtoCastArray(loc, l, a_ty); if (r_ty->ty == Tsarray) - r = DtoCastArray(r, a_ty); + r = DtoCastArray(loc, r, a_ty); } Logger::println("giving storage"); @@ -758,9 +758,9 @@ static LLValue* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool } ////////////////////////////////////////////////////////////////////////////////////////// -LLValue* DtoArrayEquals(TOK op, DValue* l, DValue* r) +LLValue* DtoArrayEquals(Loc& loc, TOK op, DValue* l, DValue* r) { - LLValue* res = DtoArrayEqCmp_impl("_adEq", l, r, true); + LLValue* res = DtoArrayEqCmp_impl(loc, "_adEq", l, r, true); res = gIR->ir->CreateICmpNE(res, DtoConstInt(0), "tmp"); if (op == TOKnotequal) res = gIR->ir->CreateNot(res, "tmp"); @@ -769,7 +769,7 @@ LLValue* DtoArrayEquals(TOK op, DValue* l, DValue* r) } ////////////////////////////////////////////////////////////////////////////////////////// -LLValue* DtoArrayCompare(TOK op, DValue* l, DValue* r) +LLValue* DtoArrayCompare(Loc& loc, TOK op, DValue* l, DValue* r) { LLValue* res = 0; @@ -817,9 +817,9 @@ LLValue* DtoArrayCompare(TOK op, DValue* l, DValue* r) { Type* t = DtoDType(DtoDType(l->getType())->next); if (t->ty == Tchar) - res = DtoArrayEqCmp_impl("_adCmpChar", l, r, false); + res = DtoArrayEqCmp_impl(loc, "_adCmpChar", l, r, false); else - res = DtoArrayEqCmp_impl("_adCmp", l, r, true); + res = DtoArrayEqCmp_impl(loc, "_adCmp", l, r, true); res = gIR->ir->CreateICmp(cmpop, res, DtoConstInt(0), "tmp"); } @@ -944,7 +944,7 @@ LLValue* DtoArrayPtr(DValue* v) } ////////////////////////////////////////////////////////////////////////////////////////// -DValue* DtoCastArray(DValue* u, Type* to) +DValue* DtoCastArray(Loc& loc, DValue* u, Type* to) { Logger::println("DtoCastArray"); LOG_SCOPE; @@ -968,6 +968,7 @@ DValue* DtoCastArray(DValue* u, Type* to) } else if (totype->ty == Tarray) { Logger::cout() << "to array" << '\n'; + const LLType* ptrty = DtoArrayType(totype)->getContainedType(1); const LLType* ety = DtoTypeNotVoid(fromtype->next); @@ -986,6 +987,13 @@ DValue* DtoCastArray(DValue* u, Type* to) Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; assert(isaPointer(uval->getType())); const LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0)); + + if(arrty->getNumElements() % totype->next->size() != 0) + { + error(loc, "invalid cast from '%s' to '%s', the element sizes don't line up", fromtype->toChars(), totype->toChars()); + fatal(); + } + rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false); rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0)); rval = DtoBitCast(uval, ptrty); diff --git a/gen/arrays.h b/gen/arrays.h index 11f1eddd..a3f16a19 100644 --- a/gen/arrays.h +++ b/gen/arrays.h @@ -30,8 +30,8 @@ DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2); void DtoStaticArrayCopy(LLValue* dst, LLValue* src); -LLValue* DtoArrayEquals(TOK op, DValue* l, DValue* r); -LLValue* DtoArrayCompare(TOK op, DValue* l, DValue* r); +LLValue* DtoArrayEquals(Loc& loc, TOK op, DValue* l, DValue* r); +LLValue* DtoArrayCompare(Loc& loc, TOK op, DValue* l, DValue* r); LLValue* DtoDynArrayIs(TOK op, DValue* l, DValue* r); @@ -40,6 +40,6 @@ LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* ne LLValue* DtoArrayLen(DValue* v); LLValue* DtoArrayPtr(DValue* v); -DValue* DtoCastArray(DValue* val, Type* to); +DValue* DtoCastArray(Loc& loc, DValue* val, Type* to); #endif // LLVMC_GEN_ARRAYS_H diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 59b88a34..0fb77f70 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -846,7 +846,7 @@ DValue* DtoCast(Loc& loc, DValue* val, Type* to) return DtoCastClass(val, to); } else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) { - return DtoCastArray(val, to); + return DtoCastArray(loc, val, to); } else if (fromtype->ty == Tpointer || fromtype->ty == Tfunction) { return DtoCastPtr(loc, val, to); diff --git a/gen/toir.cpp b/gen/toir.cpp index b78a9b14..2a96f9ec 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1309,7 +1309,7 @@ DValue* CmpExp::toElem(IRState* p) else if (t->ty == Tsarray || t->ty == Tarray) { Logger::println("static or dynamic array"); - eval = DtoArrayCompare(op,l,r); + eval = DtoArrayCompare(loc,op,l,r); } else { @@ -1382,7 +1382,7 @@ DValue* EqualExp::toElem(IRState* p) else if (t->ty == Tsarray || t->ty == Tarray) { Logger::println("static or dynamic array"); - eval = DtoArrayEquals(op,l,r); + eval = DtoArrayEquals(loc,op,l,r); } else if (t->ty == Tdelegate) {