# HG changeset patch # User Frits van Bommel # Date 1239567735 -7200 # Node ID 50dc0db06238168a41b0a7155fbbfc7d35fa9484 # Parent 3d4581761b4c92d936cabae1658afb5487118e7d# Parent e45984519be7af112fd4dbd66976333f1495b434 Merge diff -r 3d4581761b4c -r 50dc0db06238 gen/arrays.cpp --- a/gen/arrays.cpp Sun Apr 12 21:56:43 2009 +0200 +++ b/gen/arrays.cpp Sun Apr 12 22:22:15 2009 +0200 @@ -894,52 +894,67 @@ const LLType* ptrty = DtoArrayType(totype)->getContainedType(1); const LLType* ety = DtoTypeNotVoid(fromtype->nextOf()); - if (DSliceValue* usl = u->isSlice()) { + if (fromtype->ty == Tsarray) { + LLValue* uval = u->getRVal(); + if (Logger::enabled()) + Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; + + assert(isaPointer(uval->getType())); + const LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0)); + + if(arrty->getNumElements()*fromtype->nextOf()->size() % totype->nextOf()->size() != 0) { - Logger::println("from slice"); - Logger::cout() << "from: " << *usl->ptr << " to: " << *ptrty << '\n'; + error(loc, "invalid cast from '%s' to '%s', the element sizes don't line up", fromtype->toChars(), totype->toChars()); + fatal(); } - rval = DtoBitCast(usl->ptr, ptrty); - if (fromtype->nextOf()->size() == totype->nextOf()->size()) - rval2 = DtoArrayLen(usl); - else - rval2 = DtoArrayCastLength(DtoArrayLen(usl), ety, ptrty->getContainedType(0)); + + rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false); + if (fromtype->nextOf()->size() != totype->nextOf()->size()) + rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0)); + rval = DtoBitCast(uval, ptrty); } else { - if (fromtype->ty == Tsarray) { - LLValue* uval = u->getRVal(); - - if (Logger::enabled()) - Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; - - assert(isaPointer(uval->getType())); - const LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0)); - - if(arrty->getNumElements()*fromtype->nextOf()->size() % totype->nextOf()->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); - } - else { - rval2 = DtoArrayLen(u); + rval2 = DtoArrayLen(u); + if (fromtype->nextOf()->size() != totype->nextOf()->size()) rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0)); - rval = DtoArrayPtr(u); - rval = DtoBitCast(rval, ptrty); - } + rval = DtoArrayPtr(u); + rval = DtoBitCast(rval, ptrty); } isslice = true; } else if (totype->ty == Tsarray) { if (Logger::enabled()) Logger::cout() << "to sarray" << '\n'; - assert(0); + + size_t tosize = ((TypeSArray*)totype)->dim->toInteger(); + + if (fromtype->ty == Tsarray) { + LLValue* uval = u->getRVal(); + + if (Logger::enabled()) + Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; + + assert(isaPointer(uval->getType())); + const LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0)); + + /*if(arrty->getNumElements()*fromtype->nextOf()->size() != tosize*totype->nextOf()->size()) + { + error(loc, "invalid cast from '%s' to '%s', the sizes are not the same", fromtype->toChars(), totype->toChars()); + fatal(); + }*/ + + rval = DtoBitCast(uval, getPtrToType(tolltype)); + } + else { + size_t i = (tosize * totype->nextOf()->size() - 1) / fromtype->nextOf()->size(); + DConstValue index(Type::tsize_t, DtoConstSize_t(i)); + DtoArrayBoundsCheck(loc, u, &index, false); + + rval = DtoArrayPtr(u); + rval = DtoBitCast(rval, getPtrToType(tolltype)); + } } else if (totype->ty == Tbool) { // return (arr.ptr !is null) diff -r 3d4581761b4c -r 50dc0db06238 gen/toir.cpp --- a/gen/toir.cpp Sun Apr 12 21:56:43 2009 +0200 +++ b/gen/toir.cpp Sun Apr 12 22:22:15 2009 +0200 @@ -596,6 +596,23 @@ ////////////////////////////////////////////////////////////////////////////////////////// +static void errorOnIllegalArrayOp(Expression* base, Expression* e1, Expression* e2) +{ + Type* t1 = e1->type->toBasetype(); + Type* t2 = e2->type->toBasetype(); + + // valid array ops would have been transformed by optimize + if ((t1->ty == Tarray || t1->ty == Tsarray) && + (t2->ty == Tarray || t2->ty == Tsarray) + ) + { + error("Array operation %s not recognized", base->toChars()); + fatal(); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + DValue* AddExp::toElem(IRState* p) { Logger::print("AddExp::toElem: %s @ %s\n", toChars(), type->toChars()); @@ -609,6 +626,8 @@ Type* e1next = e1type->nextOf() ? e1type->nextOf()->toBasetype() : NULL; Type* e2type = e2->type->toBasetype(); + errorOnIllegalArrayOp(this, e1, e2); + if (e1type != e2type) { if (e1type->ty == Tpointer) { Logger::println("add to pointer"); @@ -648,6 +667,8 @@ Type* t1 = e1->type->toBasetype(); Type* t2 = e2->type->toBasetype(); + errorOnIllegalArrayOp(this, e1, e2); + if (t1->ty == Tpointer && t2->ty == Tpointer) { LLValue* lv = l->getRVal(); LLValue* rv = r->getRVal(); @@ -683,6 +704,8 @@ DValue* l = e1->toElem(p); DValue* r = e2->toElem(p); + errorOnIllegalArrayOp(this, e1, e2); + if (type->iscomplex()) { return DtoComplexMul(loc, type, l, r); } @@ -700,6 +723,8 @@ DValue* l = e1->toElem(p); DValue* r = e2->toElem(p); + errorOnIllegalArrayOp(this, e1, e2); + if (type->iscomplex()) { return DtoComplexDiv(loc, type, l, r); } @@ -717,6 +742,8 @@ DValue* l = e1->toElem(p); DValue* r = e2->toElem(p); + errorOnIllegalArrayOp(this, e1, e2); + return DtoBinRem(type, l, r); } @@ -1878,6 +1905,7 @@ LOG_SCOPE; \ DValue* u = e1->toElem(p); \ DValue* v = e2->toElem(p); \ + errorOnIllegalArrayOp(this, e1, e2); \ LLValue* x = llvm::BinaryOperator::Create(llvm::Instruction::Y, u->getRVal(), v->getRVal(), "tmp", p->scopebb()); \ return new DImValue(type, x); \ } diff -r 3d4581761b4c -r 50dc0db06238 runtime/CMakeLists.txt --- a/runtime/CMakeLists.txt Sun Apr 12 21:56:43 2009 +0200 +++ b/runtime/CMakeLists.txt Sun Apr 12 22:22:15 2009 +0200 @@ -2,11 +2,6 @@ cmake_minimum_required(VERSION 2.6) -find_program(GCC_EXE gcc DOC "path to gcc binary") -if(NOT GCC_EXE) - message(STATUS "gcc needs to be on your path to build the runtime") -endif(NOT GCC_EXE) - option(BUILD_SHARED_LIBS "build the runtime as shared libraries (linux only)") option(BUILD_BC_LIBS "build the runtime as bytecode libraries") option(BUILD_SINGLE_LIB "build single runtime library" ON) diff -r 3d4581761b4c -r 50dc0db06238 tests/runminitest.d --- a/tests/runminitest.d Sun Apr 12 21:56:43 2009 +0200 +++ b/tests/runminitest.d Sun Apr 12 22:22:15 2009 +0200 @@ -36,13 +36,15 @@ static int classify(char[] name) { - if (Util.containsPattern(name, "compile_")) + char[] tail; + char[] desc = Util.head(name, "_", tail); + if ("compile" == desc) return COMPILE; - else if (Util.containsPattern(name, "nocompile_")) + else if ("nocompile" == desc) return NOCOMPILE; - else if (Util.containsPattern(name, "run_")) + else if ("run" == desc) return RUN; - else if (Util.containsPattern(name, "norun_")) + else if ("norun" == desc) return NORUN; return RUN; } @@ -53,7 +55,7 @@ auto testname = Path.parse(c.name).name; Stdout.formatln("TEST NAME: {}", testname); - char[] cmd = Format.convert("ldc {} -quiet -L-s -ofobj/{} -odobj", c, testname); + char[] cmd = Format.convert("ldc {} -quiet -L-s -ofobj/{}", c, testname); foreach(v; args[1..$]) { cmd ~= ' '; cmd ~= v;