# HG changeset patch # User lindquist # Date 1191891000 -7200 # Node ID 4648206ca21347c7b27d018eae564542aff1e308 # Parent bc641b23a714f9154810784ff32e269cad4bbbfe [svn r38] * resizing dynamic arrays support * throw is replaced with assert(0) * catch is ignored * better foreach support * various bugfixes diff -r bc641b23a714 -r 4648206ca213 dmd/statement.c --- a/dmd/statement.c Thu Oct 04 22:38:53 2007 +0200 +++ b/dmd/statement.c Tue Oct 09 02:50:00 2007 +0200 @@ -1173,12 +1173,11 @@ if (arg->storageClass & (STCout | STCref | STClazy)) error("no storage class for key %s", arg->ident->toChars()); TY keyty = arg->type->ty; - if ((keyty != Tint32 && keyty != Tuns32) || - (global.params.is64bit && - keyty != Tint64 && keyty != Tuns64) + if ((keyty != Tint32 && keyty != Tuns32) && + (global.params.is64bit && keyty != Tint64 && keyty != Tuns64) ) { - error("foreach: key type must be int or uint, not %s", arg->type->toChars()); + error("foreach: key type must be %s, not %s", global.params.is64bit ? "int, uint, long or ulong" : "int or uint",arg->type->toChars()); } Initializer *ie = new ExpInitializer(0, new IntegerExp(k)); VarDeclaration *var = new VarDeclaration(loc, arg->type, arg->ident, ie); @@ -1315,13 +1314,12 @@ } if (key && - ((key->type->ty != Tint32 && key->type->ty != Tuns32) || - (global.params.is64bit && - key->type->ty != Tint64 && key->type->ty != Tuns64) + ((key->type->ty != Tint32 && key->type->ty != Tuns32) && + (global.params.is64bit && key->type->ty != Tint64 && key->type->ty != Tuns64) ) ) { - error("foreach: key type must be int or uint, not %s", key->type->toChars()); + error("foreach: key type must be %s, not %s", global.params.is64bit ? "int, uint, long or ulong" : "int or uint", key->type->toChars()); } if (key && key->storage_class & (STCout | STCref)) diff -r bc641b23a714 -r 4648206ca213 gen/arrays.c --- a/gen/arrays.c Thu Oct 04 22:38:53 2007 +0200 +++ b/gen/arrays.c Tue Oct 09 02:50:00 2007 +0200 @@ -98,7 +98,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// -llvm::Value* LLVM_DtoArrayAssign(llvm::Value* dst, llvm::Value* src) +void LLVM_DtoArrayAssign(llvm::Value* dst, llvm::Value* src) { assert(gIR); if (dst->getType() == src->getType()) @@ -118,7 +118,7 @@ llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); + new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); } else { @@ -130,14 +130,11 @@ const llvm::ArrayType* arrty = llvm::cast(src->getType()->getContainedType(0)); llvm::Type* dstty = llvm::PointerType::get(arrty->getElementType()); - llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); - - llvm::Value* dstlen = LLVM_DtoGEP(dst,zero,zero,"tmp",gIR->scopebb()); + llvm::Value* dstlen = LLVM_DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); llvm::Value* srclen = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false); new llvm::StoreInst(srclen, dstlen, gIR->scopebb()); - llvm::Value* dstptr = LLVM_DtoGEP(dst,zero,one,"tmp",gIR->scopebb()); + llvm::Value* dstptr = LLVM_DtoGEPi(dst,0,1,"tmp",gIR->scopebb()); llvm::Value* srcptr = new llvm::BitCastInst(src,dstty,"tmp",gIR->scopebb()); new llvm::StoreInst(srcptr, dstptr, gIR->scopebb()); } @@ -350,6 +347,7 @@ return ret; } +////////////////////////////////////////////////////////////////////////////////////////// void LLVM_DtoArrayCopy(elem* dst, elem* src) { Logger::cout() << "Array copy ((((" << *src->mem << ")))) into ((((" << *dst->mem << "))))\n"; @@ -387,3 +385,34 @@ values.push_back(ptr); return llvm::ConstantStruct::get(type,values); } + +////////////////////////////////////////////////////////////////////////////////////////// +void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, const llvm::Type* ty) +{ + size_t sz = gTargetData->getTypeSize(ty); + llvm::ConstantInt* n = llvm::ConstantInt::get(LLVM_DtoSize_t(), sz, false); + llvm::Value* bytesize = llvm::BinaryOperator::createMul(n,dim,"tmp",gIR->scopebb()); + + llvm::Value* nullptr = llvm::ConstantPointerNull::get(llvm::PointerType::get(ty)); + + llvm::Value* newptr = LLVM_DtoRealloc(nullptr, bytesize); + + llvm::Value* lenptr = LLVM_DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); + new llvm::StoreInst(dim,lenptr,gIR->scopebb()); + llvm::Value* ptrptr = LLVM_DtoGEPi(dst,0,1,"tmp",gIR->scopebb()); + new llvm::StoreInst(newptr,ptrptr,gIR->scopebb()); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz) +{ + llvm::Value* ptr = LLVM_DtoGEPi(arr, 0, 1, "tmp", gIR->scopebb()); + llvm::Value* ptrld = new llvm::LoadInst(ptr,"tmp",gIR->scopebb()); + llvm::Value* newptr = LLVM_DtoRealloc(ptrld, sz); + new llvm::StoreInst(newptr,ptr,gIR->scopebb()); + llvm::Value* len = LLVM_DtoGEPi(arr, 0, 0, "tmp", gIR->scopebb()); + new llvm::StoreInst(sz,len,gIR->scopebb()); +} + + + diff -r bc641b23a714 -r 4648206ca213 gen/arrays.h --- a/gen/arrays.h Thu Oct 04 22:38:53 2007 +0200 +++ b/gen/arrays.h Tue Oct 09 02:50:00 2007 +0200 @@ -2,21 +2,18 @@ #define LLVMC_GEN_ARRAYS_H const llvm::StructType* LLVM_DtoArrayType(Type* t); - const llvm::ArrayType* LLVM_DtoStaticArrayType(Type* t); +llvm::Constant* LLVM_DtoArrayInitializer(ArrayInitializer* si); +llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr); + +void LLVM_DtoArrayCopy(elem* dst, elem* src); +void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r); +void LLVM_DtoArrayAssign(llvm::Value* l, llvm::Value* r); +void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr); llvm::Value* LLVM_DtoNullArray(llvm::Value* v); -llvm::Value* LLVM_DtoArrayAssign(llvm::Value* l, llvm::Value* r); - -void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr); - -llvm::Constant* LLVM_DtoArrayInitializer(ArrayInitializer* si); - -void LLVM_DtoArrayCopy(elem* dst, elem* src); - -void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r); - -llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr); +void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, const llvm::Type* ty); +void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz); #endif // LLVMC_GEN_ARRAYS_H diff -r bc641b23a714 -r 4648206ca213 gen/elem.c --- a/gen/elem.c Thu Oct 04 22:38:53 2007 +0200 +++ b/gen/elem.c Tue Oct 09 02:50:00 2007 +0200 @@ -34,7 +34,8 @@ break; case VAR: - case REF: { + case REF: + case ARRAYLEN: if (val) { return val; } @@ -52,7 +53,6 @@ return new llvm::LoadInst(mem, "tmp", gIR->scopebb()); } } - } case VAL: case NUL: diff -r bc641b23a714 -r 4648206ca213 gen/elem.h --- a/gen/elem.h Thu Oct 04 22:38:53 2007 +0200 +++ b/gen/elem.h Tue Oct 09 02:50:00 2007 +0200 @@ -19,7 +19,8 @@ CONST, NUL, REF, - SLICE + SLICE, + ARRAYLEN }; public: diff -r bc641b23a714 -r 4648206ca213 gen/statements.c --- a/gen/statements.c Thu Oct 04 22:38:53 2007 +0200 +++ b/gen/statements.c Tue Oct 09 02:50:00 2007 +0200 @@ -35,40 +35,17 @@ Logger::println("CompoundStatement::toIR(%d):\n<<<\n%s>>>", csi++, toChars()); LOG_SCOPE; - /* - const char* labelname; - bool insterm = false; - - if (!p->scopes()) { - labelname = "bb"; - insterm = true; - } - else - labelname = "entry"; - - //if (!llvm::isa(p->topfunc()->back().back())) - // insterm = true; - - llvm::BasicBlock* bb = new llvm::BasicBlock(labelname, p->topfunc()); - - if (insterm) { - new llvm::BranchInst(bb,p->topbb()); - } - - p->bbs.push(bb); - */ - - size_t n = statements->dim; - for (size_t i=0; idim; i++) { Statement* s = (Statement*)statements->data[i]; if (s) - s->toIR(p); - else - Logger::println("NULL statement found in CompoundStatement !! :S"); + s->toIR(p); + else { + Logger::println("NULL statement found in CompoundStatement !! :S"); + assert(0); + } } - //p->bbs.pop(); } ////////////////////////////////////////////////////////////////////////////// @@ -476,17 +453,17 @@ Logger::println("TryCatchStatement::toIR(%d): %s", wsi++, toChars()); LOG_SCOPE; - assert(0 && "try-catch is not properly"); + Logger::println("*** ATTENTION: try-catch is not yet fully implemented, only the try block will be emitted."); assert(body); body->toIR(p); - assert(catches); + /*assert(catches); for(size_t i=0; idim; ++i) { Catch* c = (Catch*)catches->data[i]; c->handler->toIR(p); - } + }*/ } ////////////////////////////////////////////////////////////////////////////// @@ -497,11 +474,16 @@ Logger::println("ThrowStatement::toIR(%d): %s", wsi++, toChars()); LOG_SCOPE; - assert(0 && "throw is not implemented"); + Logger::println("*** ATTENTION: throw is not yet implemented, replacing expression with assert(0);"); + llvm::Value* line = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); + LLVM_DtoAssert(NULL, line, NULL); + + /* assert(exp); elem* e = exp->toElem(p); delete e; + */ } ////////////////////////////////////////////////////////////////////////////// @@ -622,7 +604,6 @@ LOG_SCOPE; //assert(arguments->dim == 1); - assert(key == 0); assert(value != 0); assert(body != 0); assert(aggr != 0); @@ -642,6 +623,7 @@ const llvm::Type* keytype = key ? LLVM_DtoType(key->type) : LLVM_DtoSize_t(); llvm::Value* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint()); + if (key) key->llvmValue = keyvar; const llvm::Type* valtype = LLVM_DtoType(value->type); llvm::Value* valvar = new llvm::AllocaInst(keytype, "foreachval", p->topallocapoint()); diff -r bc641b23a714 -r 4648206ca213 gen/toir.c --- a/gen/toir.c Thu Oct 04 22:38:53 2007 +0200 +++ b/gen/toir.c Tue Oct 09 02:50:00 2007 +0200 @@ -118,8 +118,10 @@ e->mem = tid->llvmValue; e->type = elem::VAR; } - else - assert(0 && "only magic supported is typeinfo"); + else { + Logger::println("unsupported: %s\n", vd->toChars()); + assert(0 && "only magic supported is typeinfo"); + } } return e; } @@ -331,9 +333,23 @@ elem* r = e2->toElem(p); p->lvals.pop_back(); + if (l->type == elem::ARRAYLEN) + { + LLVM_DtoResizeDynArray(l->mem, r->getValue()); + delete r; + delete l; + return 0; + } + // handle function argument - allocate temp storage for it :/ annoying if (l->mem == 0) { - LLVM_DtoGiveArgumentStorage(l); + assert(l->val); + if (llvm::isa(l->val)) + LLVM_DtoGiveArgumentStorage(l); + else { + Logger::cout() << "here it comes... " << *l->val << '\n'; + assert(0); + } } //e->val = l->store(r->getValue()); @@ -1826,12 +1842,16 @@ if (arguments->dim == 1) { elem* sz = ((Expression*)arguments->data[0])->toElem(p); llvm::Value* dimval = sz->getValue(); - llvm::Value* usedimval = dimval; + /*llvm::Value* usedimval = dimval; if (dimval->getType() != llvm::Type::Int32Ty) - usedimval = new llvm::TruncInst(dimval, llvm::Type::Int32Ty,"tmp",p->scopebb()); - e->mem = new llvm::MallocInst(t,usedimval,"tmp",p->scopebb()); + usedimval = new llvm::TruncInst(dimval, llvm::Type::Int32Ty,"tmp",p->scopebb());*/ - LLVM_DtoSetArray(p->toplval(), dimval, e->mem); + //e->mem = LLVM_DtoRealloc(0,t); + //new llvm::MallocInst(t,usedimval,"tmp",p->scopebb()); + + //LLVM_DtoSetArray(p->toplval(), dimval, e->mem); + + LLVM_DtoNewDynArray(p->toplval(), dimval, t); delete sz; } else { @@ -1948,11 +1968,18 @@ elem* e = new elem; elem* u = e1->toElem(p); - llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - llvm::Value* ptr = LLVM_DtoGEP(u->mem,zero,zero,"tmp",p->scopebb()); - e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb()); - e->type = elem::VAL; - + if (p->inLvalue) + { + e->mem = u->mem; + e->type = elem::ARRAYLEN; + } + else + { + llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); + llvm::Value* ptr = LLVM_DtoGEP(u->mem,zero,zero,"tmp",p->scopebb()); + e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb()); + e->type = elem::VAL; + } delete u; return e; @@ -1965,27 +1992,16 @@ Logger::print("AssertExp::toElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - elem* e = new elem; elem* u = e1->toElem(p); - elem* m = msg ? msg->toElem(p) : 0; + elem* m = msg ? msg->toElem(p) : NULL; - std::vector llargs; - llargs.resize(3); - llargs[0] = LLVM_DtoBoolean(u->getValue()); - llargs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); - llargs[2] = m ? m->val : llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); - + llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); + LLVM_DtoAssert(u->getValue(), loca, m ? m->val : NULL); + delete m; delete u; - - //Logger::cout() << *llargs[0] << '|' << *llargs[1] << '\n'; - - llvm::Function* fn = LLVM_D_GetRuntimeFunction(p->module, "_d_assert"); - assert(fn); - llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", p->scopebb()); - call->setCallingConv(llvm::CallingConv::C); - return e; + return new elem; } ////////////////////////////////////////////////////////////////////////////////////////// diff -r bc641b23a714 -r 4648206ca213 gen/tollvm.c --- a/gen/tollvm.c Thu Oct 04 22:38:53 2007 +0200 +++ b/gen/tollvm.c Tue Oct 09 02:50:00 2007 +0200 @@ -997,3 +997,66 @@ l->mem = allocainst; l->vardecl->llvmValue = l->mem; } + +////////////////////////////////////////////////////////////////////////////////////////// + +llvm::Value* LLVM_DtoRealloc(llvm::Value* ptr, const llvm::Type* ty) +{ + /*size_t sz = gTargetData->getTypeSize(ty); + llvm::ConstantInt* n = llvm::ConstantInt::get(LLVM_DtoSize_t(), sz, false); + if (ptr == 0) { + llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty); + ptr = llvm::ConstantPointerNull::get(i8pty); + } + return LLVM_DtoRealloc(ptr, n);*/ + return NULL; +} + +////////////////////////////////////////////////////////////////////////////////////////// + +llvm::Value* LLVM_DtoRealloc(llvm::Value* ptr, llvm::Value* n) +{ + assert(ptr); + assert(n); + + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_realloc"); + assert(fn); + + llvm::Value* newptr = ptr; + + llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty); + if (ptr->getType() != i8pty) { + newptr = new llvm::BitCastInst(ptr,i8pty,"tmp",gIR->scopebb()); + } + + std::vector args; + args.push_back(newptr); + args.push_back(n); + llvm::Value* ret = new llvm::CallInst(fn, args.begin(), args.end(), "tmprealloc", gIR->scopebb()); + + return ret->getType() == ptr->getType() ? ret : new llvm::BitCastInst(ret,ptr->getType(),"tmp",gIR->scopebb()); +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void LLVM_DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg) +{ + assert(loc); + std::vector llargs; + llargs.resize(3); + llargs[0] = cond ? LLVM_DtoBoolean(cond) : llvm::ConstantInt::getFalse(); + llargs[1] = loc; + llargs[2] = msg ? msg : llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); + + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assert"); + assert(fn); + llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); + call->setCallingConv(llvm::CallingConv::C); +} + + + + + + + diff -r bc641b23a714 -r 4648206ca213 gen/tollvm.h --- a/gen/tollvm.h Thu Oct 04 22:38:53 2007 +0200 +++ b/gen/tollvm.h Tue Oct 09 02:50:00 2007 +0200 @@ -44,4 +44,9 @@ void LLVM_DtoGiveArgumentStorage(elem* e); +llvm::Value* LLVM_DtoRealloc(llvm::Value* ptr, const llvm::Type* ty); +llvm::Value* LLVM_DtoRealloc(llvm::Value* ptr, llvm::Value* len); + +void LLVM_DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg); + #include "enums.h" diff -r bc641b23a714 -r 4648206ca213 lphobos/build.sh --- a/lphobos/build.sh Thu Oct 04 22:38:53 2007 +0200 +++ b/lphobos/build.sh Tue Oct 09 02:50:00 2007 +0200 @@ -9,14 +9,15 @@ # build runtime $dc_cmd internal/contract.d \ internal/arrays.d \ + internal/mem.d \ internal/moduleinit.d \ -c -noruntime -odobj || exit 1 llvm-as -f -o=obj/moduleinit_backend.bc internal/moduleinit_backend.ll || exit 1 -llvm-link -f -o=../lib/llvmdcore.bc obj/contract.bc obj/arrays.bc obj/moduleinit.bc obj/moduleinit_backend.bc || exit 1 +llvm-link -f -o=../lib/llvmdcore.bc obj/contract.bc obj/arrays.bc obj/mem.bc obj/moduleinit.bc obj/moduleinit_backend.bc || exit 1 $dc_cmd internal/objectimpl.d -c -odobj || exit 1 -llvm-link -f -o=obj/all.bc obj/contract.bc obj/arrays.bc obj/moduleinit.bc obj/objectimpl.bc obj/moduleinit_backend.bc || exit 1 +llvm-link -f -o=obj/all.bc obj/contract.bc obj/arrays.bc obj/mem.bc obj/moduleinit.bc obj/objectimpl.bc obj/moduleinit_backend.bc || exit 1 opt -f -std-compile-opts -o=../lib/llvmdcore.bc obj/all.bc || exit 1 diff -r bc641b23a714 -r 4648206ca213 lphobos/internal/mem.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lphobos/internal/mem.d Tue Oct 09 02:50:00 2007 +0200 @@ -0,0 +1,16 @@ +module internal.mem; + +extern(C): + +void* realloc(void*,size_t); +void free(void*); + +void* _d_realloc(void* ptr, size_t n) +{ + return realloc(ptr, n); +} + +void _d_free(void* ptr) +{ + free(ptr); +} diff -r bc641b23a714 -r 4648206ca213 test/arrays3.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/arrays3.d Tue Oct 09 02:50:00 2007 +0200 @@ -0,0 +1,10 @@ +module arrays3; + +void main() +{ + int[] arr; + {arr = new int[25];} + {assert(arr.length == 25);} + {arr.length = arr.length + 5;} + {assert(arr.length == 30);} +} diff -r bc641b23a714 -r 4648206ca213 test/bug7.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug7.d Tue Oct 09 02:50:00 2007 +0200 @@ -0,0 +1,14 @@ +module bug7; + +class love { } +void bug() { + love[] child; + child.length=1; + assert(child[0] is null); + child[0]=null; + assert(child[0] is null); +} +void main() +{ + bug(); +} diff -r bc641b23a714 -r 4648206ca213 test/foreach2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/foreach2.d Tue Oct 09 02:50:00 2007 +0200 @@ -0,0 +1,15 @@ +module foreach2; + +void main() +{ + static arr = [1.0, 2.0, 4.0, 8.0, 16.0]; + foreach(i,v; arr) + { + printf("arr[%d] = %f\n", i, v); + } + printf("-------------------------------\n"); + foreach_reverse(i,v; arr) + { + printf("arr[%d] = %f\n", i, v); + } +} diff -r bc641b23a714 -r 4648206ca213 test/foreach3.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/foreach3.d Tue Oct 09 02:50:00 2007 +0200 @@ -0,0 +1,19 @@ +module foreach3; + +void main() +{ + static str = ['h','e','l','l','o']; + foreach(i,v; str) { + printf("%c",v); + } + printf("\n"); + + foreach(i,v; str) { + v++; + } + + foreach(i,v; str) { + printf("%c",v); + } + printf("\n"); +} diff -r bc641b23a714 -r 4648206ca213 test/memory1.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/memory1.d Tue Oct 09 02:50:00 2007 +0200 @@ -0,0 +1,10 @@ +module memory1; + +void main() +{ + auto a = new int[16]; + {printf("array.length = %u\n", a.length);} + {a.length = a.length + 1;} + {printf("array.length = %u\n", a.length);} + {assert(a.length == 17);} +} diff -r bc641b23a714 -r 4648206ca213 test/throw1.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/throw1.d Tue Oct 09 02:50:00 2007 +0200 @@ -0,0 +1,26 @@ +module throw1; + +extern(C) int rand(); + +class C +{ +} + +void func() +{ + if (rand() & 1) + throw new C; +} + +int main() +{ + try + { + func(); + } + catch(Object) + { + return 1; + } + return 0; +}