# HG changeset patch # User lindquist # Date 1193624892 -3600 # Node ID d7e764e62462616c69b5561d849e3b3dd93a745a # Parent 53d3086b5ad33c617e9fcdd8d3d70b18be55470a [svn r76] Fixed: TypeInfo for structs. Fixed: PostExp was unable to allocate storage for parameters. Fixed: Many types of functions and delegates were broken. Misc cleanups. diff -r 53d3086b5ad3 -r d7e764e62462 dmd/aggregate.h --- a/dmd/aggregate.h Sun Oct 28 19:48:57 2007 +0100 +++ b/dmd/aggregate.h Mon Oct 29 03:28:12 2007 +0100 @@ -98,7 +98,7 @@ bool llvmInProgress; llvm::Type* llvmType; - llvm::Value* llvmVtbl; + llvm::Constant* llvmVtbl; llvm::ConstantStruct* llvmConstVtbl; llvm::Constant* llvmInitZ; virtual void offsetToIndex(Type* t, unsigned os, std::vector& result); // converts a DMD field offsets to LLVM struct index vector diff -r 53d3086b5ad3 -r d7e764e62462 dmd/mtype.h --- a/dmd/mtype.h Sun Oct 28 19:48:57 2007 +0100 +++ b/dmd/mtype.h Mon Oct 29 03:28:12 2007 +0100 @@ -540,7 +540,7 @@ type *toCtype(); - llvm::Value* llvmInit; + llvm::Constant* llvmInit; }; struct TypeEnum : Type @@ -638,7 +638,7 @@ Symbol *toSymbol(); - llvm::Value* llvmInit; + llvm::Constant* llvmInit; }; struct TypeTuple : Type diff -r 53d3086b5ad3 -r d7e764e62462 gen/toir.c --- a/gen/toir.c Sun Oct 28 19:48:57 2007 +0100 +++ b/gen/toir.c Mon Oct 29 03:28:12 2007 +0100 @@ -116,6 +116,7 @@ // _arguments if (vd->ident == Id::_arguments) { + Logger::println("Id::_arguments"); vd->llvmValue = p->func().decl->llvmArguments; assert(vd->llvmValue); e->mem = vd->llvmValue; @@ -124,6 +125,7 @@ // _argptr else if (vd->ident == Id::_argptr) { + Logger::println("Id::_argptr"); vd->llvmValue = p->func().decl->llvmArgPtr; assert(vd->llvmValue); e->mem = vd->llvmValue; @@ -132,6 +134,7 @@ // _dollar else if (vd->ident == Id::dollar) { + Logger::println("Id::dollar"); assert(!p->arrays.empty()); llvm::Value* tmp = LLVM_DtoGEPi(p->arrays.back(),0,0,"tmp",p->scopebb()); e->val = new llvm::LoadInst(tmp,"tmp",p->scopebb()); @@ -152,6 +155,7 @@ } // nested variable else if (vd->nestedref) { + Logger::println("nested variable"); e->mem = LLVM_DtoNestedVariable(vd); e->type = elem::VAR; e->vardecl = vd; @@ -159,7 +163,11 @@ // function parameter else if (vd->isParameter()) { Logger::println("function param"); - assert(vd->llvmValue); + if (!vd->llvmValue) { + // TODO: determine this properly + // this happens when the DMD frontend generates by pointer wrappers for struct opEquals(S) and opCmp(S) + vd->llvmValue = &p->func().func->getArgumentList().back(); + } if (vd->isRef() || vd->isOut()) { e->mem = vd->llvmValue; e->type = elem::VAR; @@ -1432,18 +1440,27 @@ assert(vd->llvmValue); Type* t = LLVM_DtoDType(type); + Type* tnext = LLVM_DtoDType(t->next); Type* vdtype = LLVM_DtoDType(vd->type); llvm::Value* llvalue = vd->nestedref ? LLVM_DtoNestedVariable(vd) : vd->llvmValue; if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) { TypeStruct* vdt = (TypeStruct*)vdtype; + assert(vdt->sym); e = new elem; - std::vector dst(1,0); - vdt->sym->offsetToIndex(t->next, offset, dst); - llvm::Value* ptr = llvalue; - assert(ptr); - e->mem = LLVM_DtoGEP(ptr,dst,"tmp"); + bool donormally = true; + if (offset == 0) { + const llvm::Type* llt = LLVM_DtoType(t); + e->mem = p->ir->CreateBitCast(llvalue, llt, "tmp"); + } + else { + std::vector dst(1,0); + vdt->sym->offsetToIndex(tnext, offset, dst); + llvm::Value* ptr = llvalue; + assert(ptr); + e->mem = LLVM_DtoGEP(ptr,dst,"tmp"); + } e->type = elem::VAL; e->field = true; } @@ -2118,7 +2135,8 @@ else assert(post); - //llvm::Value* tostore = l->storeVal ? l->storeVal : l->val; + if (l->mem == 0) + LLVM_DtoGiveArgumentStorage(l); new llvm::StoreInst(post,l->mem,p->scopebb()); delete l; diff -r 53d3086b5ad3 -r d7e764e62462 gen/tollvm.c --- a/gen/tollvm.c Sun Oct 28 19:48:57 2007 +0100 +++ b/gen/tollvm.c Mon Oct 29 03:28:12 2007 +0100 @@ -151,7 +151,7 @@ case Tfunction: { if (t->llvmType == 0) { - return LLVM_DtoFunctionType(t); + return LLVM_DtoFunctionType(t,NULL); } else { return t->llvmType; @@ -188,94 +188,13 @@ ////////////////////////////////////////////////////////////////////////////////////////// -const llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam) +const llvm::FunctionType* LLVM_DtoFunctionType(Type* type, const llvm::Type* thistype, bool ismain) { - TypeFunction* f = (TypeFunction*)t; - - // parameter types - const llvm::Type* rettype; - std::vector paramvec; - - if (LLVM_DtoIsPassedByRef(f->next)) { - rettype = llvm::PointerType::get(LLVM_DtoType(f->next)); - paramvec.push_back(rettype); - rettype = llvm::Type::VoidTy; - } - else { - Type* rt = f->next; - if (rt) - rettype = LLVM_DtoType(rt); - else - assert(0); - } - - if (thisparam) { - paramvec.push_back(thisparam); - } - - size_t n = Argument::dim(f->parameters); - for (int i=0; i < n; ++i) { - Argument* arg = Argument::getNth(f->parameters, i); - // ensure scalar - Type* argT = arg->type; - assert(argT); - paramvec.push_back(LLVM_DtoType(argT)); - } - - Logger::cout() << "Return type: " << *rettype << '\n'; - - llvm::FunctionType* functype = llvm::FunctionType::get(rettype, paramvec, f->varargs); - return functype; -} - -////////////////////////////////////////////////////////////////////////////////////////// - -static const llvm::FunctionType* LLVM_DtoVaFunctionType(FuncDeclaration* fdecl) -{ - TypeFunction* f = (TypeFunction*)fdecl->type; + TypeFunction* f = (TypeFunction*)type; assert(f != 0); - const llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty); - std::vector args; - - if (fdecl->llvmInternal == LLVMva_start) { - args.push_back(i8pty); - } - else if (fdecl->llvmInternal == LLVMva_intrinsic) { - size_t n = Argument::dim(f->parameters); - for (size_t i=0; illvmType = fty; - return fty; -} - -////////////////////////////////////////////////////////////////////////////////////////// - -const llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl) -{ - if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) { - return LLVM_DtoVaFunctionType(fdecl); - } - - TypeFunction* f = (TypeFunction*)fdecl->type; - assert(f != 0); - - // type has already been resolved - if (f->llvmType != 0) { - return llvm::cast(f->llvmType); - } - bool typesafeVararg = false; if (f->linkage == LINKd && f->varargs == 1) { - assert(fdecl->v_arguments); - Logger::println("v_arguments = %s", fdecl->v_arguments->toChars()); - assert(fdecl->v_arguments->isParameter()); typesafeVararg = true; } @@ -286,11 +205,12 @@ bool retinptr = false; bool usesthis = false; - if (fdecl->isMain()) { + if (ismain) { rettype = llvm::Type::Int32Ty; actualRettype = rettype; } - else if (rt) { + else { + assert(rt); if (LLVM_DtoIsPassedByRef(rt)) { rettype = llvm::PointerType::get(LLVM_DtoType(rt)); actualRettype = llvm::Type::VoidTy; @@ -301,9 +221,6 @@ actualRettype = rettype; } } - else { - assert(0); - } // parameter types std::vector paramvec; @@ -313,21 +230,8 @@ paramvec.push_back(rettype); } - if (fdecl->needThis()) { - if (AggregateDeclaration* ad = fdecl->isMember()) { - Logger::print("isMember = this is: %s\n", ad->type->toChars()); - const llvm::Type* thisty = LLVM_DtoType(ad->type); - Logger::cout() << "this llvm type: " << *thisty << '\n'; - if (llvm::isa(thisty) || thisty == gIR->topstruct().recty.get()) - thisty = llvm::PointerType::get(thisty); - paramvec.push_back(thisty); - usesthis = true; - } - else - assert(0); - } - else if (fdecl->isNested()) { - paramvec.push_back(llvm::PointerType::get(llvm::Type::Int8Ty)); + if (thistype) { + paramvec.push_back(thistype); usesthis = true; } @@ -396,7 +300,6 @@ bool isvararg = !typesafeVararg && f->varargs; llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); - f->llvmType = functype; f->llvmRetInPtr = retinptr; f->llvmUsesThis = usesthis; return functype; @@ -404,6 +307,67 @@ ////////////////////////////////////////////////////////////////////////////////////////// +static const llvm::FunctionType* LLVM_DtoVaFunctionType(FuncDeclaration* fdecl) +{ + TypeFunction* f = (TypeFunction*)fdecl->type; + assert(f != 0); + + const llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty); + std::vector args; + + if (fdecl->llvmInternal == LLVMva_start) { + args.push_back(i8pty); + } + else if (fdecl->llvmInternal == LLVMva_intrinsic) { + size_t n = Argument::dim(f->parameters); + for (size_t i=0; illvmType = fty; + return fty; +} + +////////////////////////////////////////////////////////////////////////////////////////// + +const llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl) +{ + if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) { + return LLVM_DtoVaFunctionType(fdecl); + } + + // type has already been resolved + if (fdecl->type->llvmType != 0) { + return llvm::cast(fdecl->type->llvmType); + } + + const llvm::Type* thisty = NULL; + if (fdecl->needThis()) { + if (AggregateDeclaration* ad = fdecl->isMember()) { + Logger::print("isMember = this is: %s\n", ad->type->toChars()); + thisty = LLVM_DtoType(ad->type); + Logger::cout() << "this llvm type: " << *thisty << '\n'; + if (llvm::isa(thisty) || thisty == gIR->topstruct().recty.get()) + thisty = llvm::PointerType::get(thisty); + } + else + assert(0); + } + else if (fdecl->isNested()) { + thisty = llvm::PointerType::get(llvm::Type::Int8Ty); + } + + const llvm::FunctionType* functype = LLVM_DtoFunctionType(fdecl->type, thisty, fdecl->isMain()); + fdecl->type->llvmType = functype; + return functype; +} + +////////////////////////////////////////////////////////////////////////////////////////// + const llvm::StructType* LLVM_DtoDelegateType(Type* t) { const llvm::Type* i8ptr = llvm::PointerType::get(llvm::Type::Int8Ty); diff -r 53d3086b5ad3 -r d7e764e62462 gen/tollvm.h --- a/gen/tollvm.h Sun Oct 28 19:48:57 2007 +0100 +++ b/gen/tollvm.h Mon Oct 29 03:28:12 2007 +0100 @@ -11,7 +11,7 @@ llvm::Value* LLVM_DtoStructCopy(llvm::Value* dst, llvm::Value* src); llvm::Constant* LLVM_DtoConstStructInitializer(StructInitializer* si); -const llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam = 0); +const llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thistype, bool ismain = false); const llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl); llvm::Function* LLVM_DtoDeclareFunction(FuncDeclaration* fdecl); diff -r 53d3086b5ad3 -r d7e764e62462 gen/toobj.c --- a/gen/toobj.c Sun Oct 28 19:48:57 2007 +0100 +++ b/gen/toobj.c Mon Oct 29 03:28:12 2007 +0100 @@ -296,7 +296,8 @@ gIR->structs.pop_back(); // generate typeinfo - //type->getTypeInfo(NULL); + if (getModule() == gIR->dmodule) + type->getTypeInfo(NULL); } /* ================================================================== */ @@ -624,8 +625,7 @@ LOG_SCOPE; // generate typeinfo - if (!type->builtinTypeInfo()) - type->getTypeInfo(NULL); + type->getTypeInfo(NULL); } /* ================================================================== */ diff -r 53d3086b5ad3 -r d7e764e62462 gen/typinf.c --- a/gen/typinf.c Sun Oct 28 19:48:57 2007 +0100 +++ b/gen/typinf.c Mon Oct 29 03:28:12 2007 +0100 @@ -263,12 +263,6 @@ void TypeInfoDeclaration::toDt(dt_t **pdt) { assert(0 && "TypeInfoDeclaration"); - - /* - //printf("TypeInfoDeclaration::toDt() %s\n", toChars()); - dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo - dtdword(pdt, 0); // monitor - */ } /* ========================================================================= */ @@ -316,7 +310,6 @@ if (tinfo->isZeroInit() || !sd->init) // 0 initializer, or the same as the base type { sinits.push_back(LLVM_DtoConstSlice(LLVM_DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt))); - //sinits.push_back(initZ->getOperand(3)); } else { @@ -334,43 +327,6 @@ llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,toChars(),gIR->module); llvmValue = gvar; - - /* - dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef - dtdword(pdt, 0); // monitor - - assert(tinfo->ty == Ttypedef); - - TypeTypedef *tc = (TypeTypedef *)tinfo; - TypedefDeclaration *sd = tc->sym; - //printf("basetype = %s\n", sd->basetype->toChars()); - - // Put out: - // TypeInfo base; - // char[] name; - // void[] m_init; - - sd->basetype = sd->basetype->merge(); - sd->basetype->getTypeInfo(NULL); // generate vtinfo - assert(sd->basetype->vtinfo); - dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype - - char *name = sd->toPrettyChars(); - size_t namelen = strlen(name); - dtdword(pdt, namelen); - dtabytes(pdt, TYnptr, 0, namelen + 1, name); - - // void[] init; - if (tinfo->isZeroInit() || !sd->init) - { // 0 initializer, or the same as the base type - dtdword(pdt, 0); // init.length - dtdword(pdt, 0); // init.ptr - } - else - { - dtdword(pdt, sd->type->size()); // init.length - dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr - */ } /* ========================================================================= */ @@ -418,7 +374,6 @@ if (tinfo->isZeroInit() || !sd->defaultval) // 0 initializer, or the same as the base type { sinits.push_back(LLVM_DtoConstSlice(LLVM_DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt))); - //sinits.push_back(initZ->getOperand(3)); } else { @@ -437,44 +392,6 @@ llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,toChars(),gIR->module); llvmValue = gvar; - - /* - - //printf("TypeInfoEnumDeclaration::toDt()\n"); - dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum - dtdword(pdt, 0); // monitor - - assert(tinfo->ty == Tenum); - - TypeEnum *tc = (TypeEnum *)tinfo; - EnumDeclaration *sd = tc->sym; - - // Put out: - // TypeInfo base; - // char[] name; - // void[] m_init; - - sd->memtype->getTypeInfo(NULL); - dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for enum members - - char *name = sd->toPrettyChars(); - size_t namelen = strlen(name); - dtdword(pdt, namelen); - dtabytes(pdt, TYnptr, 0, namelen + 1, name); - - // void[] init; - if (tinfo->isZeroInit() || !sd->defaultval) - { // 0 initializer, or the same as the base type - dtdword(pdt, 0); // init.length - dtdword(pdt, 0); // init.ptr - } - else - { - dtdword(pdt, sd->type->size()); // init.length - dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr - } - - */ } /* ========================================================================= */ @@ -610,7 +527,166 @@ void TypeInfoStructDeclaration::toDt(dt_t **pdt) { - assert(0 && "TypeInfoStructDeclaration"); + Logger::println("TypeInfoStructDeclaration::toDt() %s", toChars()); + LOG_SCOPE; + + assert(tinfo->ty == Tstruct); + TypeStruct *tc = (TypeStruct *)tinfo; + StructDeclaration *sd = tc->sym; + + ClassDeclaration* base = Type::typeinfostruct; + base->toObjFile(); + + const llvm::StructType* stype = llvm::cast(base->llvmType); + + std::vector sinits; + sinits.push_back(base->llvmVtbl); + + // char[] name + char *name = sd->toPrettyChars(); + sinits.push_back(LLVM_DtoConstString(name)); + assert(sinits.back()->getType() == stype->getElementType(1)); + + // void[] init + const llvm::PointerType* initpt = llvm::PointerType::get(llvm::Type::Int8Ty); + if (sd->zeroInit) // 0 initializer, or the same as the base type + { + sinits.push_back(LLVM_DtoConstSlice(LLVM_DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt))); + } + else + { + assert(sd->llvmInitZ); + size_t cisize = gTargetData->getTypeSize(tc->llvmType); + llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(tc->llvmInit, initpt); + sinits.push_back(LLVM_DtoConstSlice(LLVM_DtoConstSize_t(cisize), cicast)); + } + + // toX functions ground work + FuncDeclaration *fd; + FuncDeclaration *fdx; + TypeFunction *tf; + Type *ta; + Dsymbol *s; + + static TypeFunction *tftohash; + static TypeFunction *tftostring; + + if (!tftohash) + { + Scope sc; + + tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd); + tftohash = (TypeFunction *)tftohash->semantic(0, &sc); + + tftostring = new TypeFunction(NULL, Type::tchar->arrayOf(), 0, LINKd); + tftostring = (TypeFunction *)tftostring->semantic(0, &sc); + } + + TypeFunction *tfeqptr; + { + Scope sc; + Arguments *arguments = new Arguments; + Argument *arg = new Argument(STCin, tc->pointerTo(), NULL, NULL); + + arguments->push(arg); + tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd); + tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc); + } + +#if 0 + TypeFunction *tfeq; + { + Scope sc; + Array *arguments = new Array; + Argument *arg = new Argument(In, tc, NULL, NULL); + + arguments->push(arg); + tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd); + tfeq = (TypeFunction *)tfeq->semantic(0, &sc); + } +#endif + + const llvm::PointerType* ptty = llvm::cast(stype->getElementType(3)); + + s = search_function(sd, Id::tohash); + fdx = s ? s->isFuncDeclaration() : NULL; + if (fdx) + { + fd = fdx->overloadExactMatch(tftohash); + if (fd) { + assert(fd->llvmValue != 0); + llvm::Constant* c = llvm::cast_or_null(fd->llvmValue); + assert(c); + c = llvm::ConstantExpr::getBitCast(c, ptty); + sinits.push_back(c); + } + else { + //fdx->error("must be declared as extern (D) uint toHash()"); + sinits.push_back(llvm::ConstantPointerNull::get(ptty)); + } + } + else { + sinits.push_back(llvm::ConstantPointerNull::get(ptty)); + } + + s = search_function(sd, Id::eq); + fdx = s ? s->isFuncDeclaration() : NULL; + for (int i = 0; i < 2; i++) + { + ptty = llvm::cast(stype->getElementType(4+i)); + if (fdx) + { + fd = fdx->overloadExactMatch(tfeqptr); + if (fd) { + assert(fd->llvmValue != 0); + llvm::Constant* c = llvm::cast_or_null(fd->llvmValue); + assert(c); + c = llvm::ConstantExpr::getBitCast(c, ptty); + sinits.push_back(c); + } + else { + //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars()); + sinits.push_back(llvm::ConstantPointerNull::get(ptty)); + } + } + else { + sinits.push_back(llvm::ConstantPointerNull::get(ptty)); + } + + s = search_function(sd, Id::cmp); + fdx = s ? s->isFuncDeclaration() : NULL; + } + + ptty = llvm::cast(stype->getElementType(6)); + s = search_function(sd, Id::tostring); + fdx = s ? s->isFuncDeclaration() : NULL; + if (fdx) + { + fd = fdx->overloadExactMatch(tftostring); + if (fd) { + assert(fd->llvmValue != 0); + llvm::Constant* c = llvm::cast_or_null(fd->llvmValue); + assert(c); + c = llvm::ConstantExpr::getBitCast(c, ptty); + sinits.push_back(c); + } + else { + //fdx->error("must be declared as extern (D) char[] toString()"); + sinits.push_back(llvm::ConstantPointerNull::get(ptty)); + } + } + else { + sinits.push_back(llvm::ConstantPointerNull::get(ptty)); + } + + // uint m_flags; + sinits.push_back(LLVM_DtoConstUint(tc->hasPointers())); + + // create the symbol + llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); + llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,toChars(),gIR->module); + + llvmValue = gvar; /* //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars()); diff -r 53d3086b5ad3 -r d7e764e62462 lphobos/internal/objectimpl.d --- a/lphobos/internal/objectimpl.d Sun Oct 28 19:48:57 2007 +0100 +++ b/lphobos/internal/objectimpl.d Mon Oct 29 03:28:12 2007 +0100 @@ -937,6 +937,8 @@ ClassInfo info; } ++/ + class TypeInfo_Struct : TypeInfo { char[] toString() { return name; } @@ -987,7 +989,7 @@ return c; } - int compare(void *p2, void *p1) + int compare(void *p1, void *p2) { int c = 0; @@ -1029,6 +1031,8 @@ uint m_flags; } +/+ + class TypeInfo_Tuple : TypeInfo { TypeInfo[] elements; diff -r 53d3086b5ad3 -r d7e764e62462 test/bug38.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug38.d Mon Oct 29 03:28:12 2007 +0100 @@ -0,0 +1,12 @@ +module bug38; + +void func(int* p) +{ + p++; +} + +void main() +{ + int i; + func(&i); +} diff -r 53d3086b5ad3 -r d7e764e62462 test/bug39.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug39.d Mon Oct 29 03:28:12 2007 +0100 @@ -0,0 +1,13 @@ +module bug39; + +struct S +{ + long l; +} + +void main() +{ + S s; + s.l = 23; + void* p = &s; +} diff -r 53d3086b5ad3 -r d7e764e62462 test/bug40.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug40.d Mon Oct 29 03:28:12 2007 +0100 @@ -0,0 +1,12 @@ +module bug40; + +char[] func(void* p) +{ + return null; +} + +void main() +{ + char[] function(void*) fp = &func; + assert(fp(null) is null); +} diff -r 53d3086b5ad3 -r d7e764e62462 test/typeinfo10.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/typeinfo10.d Mon Oct 29 03:28:12 2007 +0100 @@ -0,0 +1,64 @@ +module typeinfo10; + +struct S +{ + long l; + float f; + void* vp; + + hash_t toHash() + { + return l + cast(size_t)f; + } + + int opEquals(S s) + { + return (s.l == l) && (s.f == f); + } + + int opCmp(S a) + { + if (l == a.l) { + return (f < a.f) ? -1 : (f > a.f) ? 1 : 0; + } + return (l < a.l) ? -1 : 1; + } + + char[] toString() + { + return "S instance"; + } +} + +void main() +{ + S s=S(-1, 0); + S t=S(-1, 1); + S u=S(11,-1); + S v=S(12,13); + + { + assert(s == s); + assert(s != t); + assert(s != v); + assert(s < t); + assert(u > s); + assert(v > u); + } + + { + auto ti = typeid(S); + assert(ti.getHash(&s) == s.toHash()); + assert(ti.equals(&s,&s)); + assert(!ti.equals(&s,&t)); + assert(!ti.equals(&s,&v)); + assert(ti.compare(&s,&s) == 0); + assert(ti.compare(&s,&t) < 0); + assert(ti.compare(&u,&s) > 0); + assert(ti.compare(&v,&u) > 0); + { + auto tis = cast(TypeInfo_Struct)ti; + assert(tis.xtoString(&s) == s.toString()); + } + } +}